diff --git a/16col/adf.coffee b/16col/adf.coffee new file mode 100644 index 0000000..937295b --- /dev/null +++ b/16col/adf.coffee @@ -0,0 +1,44 @@ +class @ImageTextModeADF extends @ImageTextMode + + COLOR_INDEX = [ 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63 ] + + constructor: ( options ) -> + super + @header = { version: 0 } + this[k] = v for own k, v of options + + parse: ( content ) -> + @header.version = @getByteAt( content, 0 ) + @parsePaletteData( content.substr( 1, 192 ) ) + @parseFontData( content.substr( 193, 4096 ) ) + + x = 0 + y = 0 + @screen[ y ] = [] + + for i in [ 4289 .. content.length - 2 ] by 2 + ch = content.substr( i, 1 ) + break if ch == "\x1a" + attr = @getByteAt( content, i + 1 ) + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x == 80 + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + + parsePaletteData: ( data ) -> + colors = [] + for i in COLOR_INDEX + j = i * 3 + r = @getByteAt( data, j ) + r = r << 2 | r >> 4 + g = @getByteAt( data, j + 1 ) + g = g << 2 | g >> 4 + b = @getByteAt( data, j + 2 ) + b = b << 2 | b >> 4 + colors.push [ r, g, b ] + + @palette = new ImageTextModePalette( { colors: colors } ) diff --git a/16col/ansi.coffee b/16col/ansi.coffee new file mode 100644 index 0000000..bd479b6 --- /dev/null +++ b/16col/ansi.coffee @@ -0,0 +1,179 @@ + +class @ImageTextModeANSI extends @ImageTextMode + constructor: ( options ) -> + super @screen + super @font + @palette = new ImageTextModePaletteANSI + @tabstop = 8 + @linewrap = 80 + @[k] = v for own k, v of options + + ANSI_ESC = String.fromCharCode(0x1b) + ANSI_CSI = ANSI_ESC + '[' + ANSI_TEXT_PROP = 'm' + ANSI_RESET = '0' + ANSI_FG = '3' + ANSI_BG = '4' + ANSI_FG_INTENSE = '9' + ANSI_BG_INTENSE = '10' + ANSI_CUR_DOWN = 'B' + ANSI_SEP = ';' + ANSI_RETURN = 'A' + +# not going to mess with this for now, as I think it is the 'write' code +# for the actual ansi editor. That would be bad to mess up. +# did redo the for loops to read nicer tho. + + write: -> + content = "#{ ANSI_CSI }2J" # initiate document + for y in [0...@screen.length] + content += "\n" if !@screen[y]? + continue if !@screen[y]? + for x in [0...@getWidth()] + pixel = @screen[y][x] + if !pixel? + pixel = { ch: ' ', attr: 7 } + attr = @gen_args(pixel.attr) + if (attr != prevattr) + content += "#{ANSI_CSI}0;#{attr}#{ANSI_TEXT_PROP}" + prevattr = attr + content += if pixel.ch? then pixel.ch else ' ' + max_x = x + content += "#{ ANSI_CSI }0m" + @toBinaryArray(content) + + gen_args: ( attr ) -> + fg = 30 + ( attr & 7 ) + bg = 40 + ( ( attr & 112 ) >> 4) + bl = if attr & 128 then 5 else '' + intense = if attr & 8 then 1 else '' + +# um why do we make this attrs variable and not use it? + + attrs = a for a in [fg, bg, bl, intense] when a != '' + return [fg, bg, bl, intense].join(";") + + parse: ( content ) -> + @screen = [] + @state = 0 + @x = 0 + @y = 0 + @save_x = 0 + @save_y = 0 + @attr = 7 + @argbuf = '' + + content = content.split( '' ) + while ch = content.shift() + if @state is 0 + switch ch + when "\x1a" then @state = 3 + when "\x1b" then @state = 1 + when "\n" + @x = 0 + @y++ + when "\r" then break + when "\t" + i = ( @x + 1 ) % @tabstop + @putpixel ' ' while i-- > 0 + else + @putpixel ch + + else if @state is 1 + if ch isnt "[" + @putpixel "\x1b" + @putpixel "[" + @state = 0 + else + @state = 2 + + else if @state is 2 + if ch.match( '[A-Za-z]' ) + args = ( parseInt( i ) for i in @argbuf.split ';' ) + + switch ch + when "m" + for arg in args + if arg is 0 + @attr = 7 + else if arg is 1 + @attr |= 8 + else if arg is 5 + @attr |= 128 + else if 30 <= arg <= 37 + @attr &= 248 + @attr |= ( arg - 30 ) + else if 40 <= arg <= 47 + @attr &= 143 + @attr |= ( arg - 40 ) << 4 + + when "H", "f" + @y = ( args[ 0 ] or 1 ) - 1 + @x = ( args[ 1 ] or 1 ) - 1 + @y = 0 if @y < 0 + @x = 0 if @x < 0 + when "A" + @y -= args[ 0 ] or 1 + @y = 0 if @y < 0 + when "B" + @y += args[ 0 ] or 1 + when "C" + @x += args[ 0 ] or 1 + when "D" + @x -= args[ 0 ] or 1 + @x = 0 if @x < 0 + when "E" + @y += args[ 0 ] or 1 + @x = 0 + when "F" + @y -= args[ 0 ] or 1 + @y = 0 if @y > 0 + @x = 0 + when "G" + @x = ( args[ 0 ] or 1 ) - 1 + when "s" + @save_x = @x + @save_y = @y + when "u" + @x = @save_x + @y = @save_y + when "J" + if args.length is 0 or args[ 0 ] is 0 + @screen[ i ] = null for i in [ @y + 1 .. screen.length - 1 ] + @screen[ @y ][ i ] = null for i in [ @x .. screen[ @y ].length - 1 ] + else if args[ 0 ] is 1 + @screen[ i ] = null for i in [ 0 .. @y - 1 ] + @screen[ @y ][ i ] = null for i in [ 0 .. @x ] + else if args[ 0 ] is 2 + @x = 0 + @y = 0 + @screen = [] + when "K" + if args.length is 0 or args[ 0 ] is 0 + @screen[ @y ][ i ] = null for i in [ @x .. @screen[ @y ].length - 1 ] + else if args[ 0 ] is 1 + @screen[ @y ][ i ] = null for i in [ 0 .. @x ] + else if args[ 0 ] is 2 + @screen[ @y ] = null + + @argbuf = '' + @state = 0 + + else + @argbuf += ch + + else if @state is 3 + break + + else + @state = 0 + + + putpixel: ( ch ) -> + @screen[ @y ] = [] if !@screen[ @y ]? + @screen[ @y ][ @x ] = { ch: ch, attr: @attr } + + if ++@x >= @linewrap + @x = 0 + @y++ + diff --git a/16col/avatar.coffee b/16col/avatar.coffee new file mode 100644 index 0000000..e47568e --- /dev/null +++ b/16col/avatar.coffee @@ -0,0 +1,68 @@ +class @ImageTextModeAVATAR extends @ImageTextMode + + constructor: ( options ) -> + super + @tabstop = 8 + @linewrap = 80 + this[k] = v for own k, v of options + + parse: ( content ) -> + @screen = [] + @x = 0 + @y = 0 + @attr = 3 + + content = content.split( '' ) + while ch = content.shift() + if ch is "\x1a" + break + else if ch is "\n" + @x = 0 + @y++ + else if ch is "\r" + continue + else if ch is "\t" + i = ( @x + 1 ) % @tabstop + @putpixel ' ' while i-- > 0 + else if ch.charCodeAt( 0 ) is 12 + @screen = [] + @attr = 3 + @insert = false + else if ch.charCodeAt( 0 ) is 25 + ch = content.shift() + i = content.shift().charCodeAt( 0 ) + @putpixel( ch ) while i-- > 0 + else if ch.charCodeAt( 0 ) is 22 + c = content.shift().charCodeAt( 0 ) + switch c + when 1 + @attr = content.shift().charCodeAt( 0 ) & 0x7f + when 2 + @attr |= 0x80 + when 3 + @y-- + @y = 0 if @y < 0 + when 4 + @y++ + when 5 + @x-- + @x = 0 if @x < 0 + when 6 + @x++ + when 7 + @screen[ @y ][ i ] = null for i in [ @x .. screen[ @y ].length - 1 ] + when 8 + @y = content.shift().charCodeAt( 0 ) - 1 + @x = content.shift().charCodeAt( 0 ) - 1 + @y = 0 if @y < 0 + @x = 0 if @x < 0 + else + @putpixel ch + + putpixel: ( ch ) -> + @screen[ @y ] = [] if !@screen[ @y ]? + @screen[ @y ][ @x ] = { ch: ch, attr: @attr } + + if ++@x >= @linewrap + @x = 0 + @y++ diff --git a/16col/bin.coffee b/16col/bin.coffee new file mode 100644 index 0000000..e81e515 --- /dev/null +++ b/16col/bin.coffee @@ -0,0 +1,25 @@ +class @ImageTextModeBin extends @ImageTextMode + + constructor: ( options ) -> + super + @linewrap = 160 + this[k] = v for own k, v of options + + parse: ( content ) -> + x = 0 + y = 0 + @screen[ y ] = [] + + for i in [ 0 .. content.length - 2 ] by 2 + ch = content.substr( i, 1 ) + break if ch == "\x1a" + attr = @getByteAt( content, i + 1 ) + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x == @linewrap + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + diff --git a/16col/fonts.coffee b/16col/fonts.coffee new file mode 100644 index 0000000..d7c4206 --- /dev/null +++ b/16col/fonts.coffee @@ -0,0 +1,797 @@ +class @ImageTextModeFont + constructor: ( options ) -> + @chars = [] + @width = 8 + @[k] = v for own k, v of options + +class @ImageTextModeFont8x16 extends @ImageTextModeFont + constructor: ( options ) -> + super @width + @chars = [ + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff ], + [ 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 ], + [ 0x00, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x1c, 0x36, 0x32, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00 ], + [ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00 ], + [ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x70, 0x00, 0x00 ], + [ 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0x00, 0x00 ], + [ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x38, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00 ], + [ 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 ], + [ 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00 ], + [ 0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x66, 0xce, 0x9a, 0x3f, 0x06, 0x06, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44 ], + [ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa ], + [ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], + [ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 ], + [ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f ], + [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x6c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x3c, 0x66, 0x0c, 0x18, 0x32, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] + ] + @height = 16 + @[k] = v for own k, v of options + +class @ImageTextModeFont8x8 extends @ImageTextModeFont + constructor: ( options ) -> + super @width + @chars = [ + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e ], + [ 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e ], + [ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00 ], + [ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00 ], + [ 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0xd6, 0x10, 0x38 ], + [ 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x7c, 0x10, 0x38 ], + [ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00 ], + [ 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff ], + [ 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00 ], + [ 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff ], + [ 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78 ], + [ 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18 ], + [ 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0 ], + [ 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0 ], + [ 0x18, 0xdb, 0x3c, 0xe7, 0xe7, 0x3c, 0xdb, 0x18 ], + [ 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00 ], + [ 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00 ], + [ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18 ], + [ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 ], + [ 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00 ], + [ 0x3e, 0x61, 0x3c, 0x66, 0x66, 0x3c, 0x86, 0x7c ], + [ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00 ], + [ 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff ], + [ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00 ], + [ 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00 ], + [ 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00 ], + [ 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00 ], + [ 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00 ], + [ 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00 ], + [ 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00 ], + [ 0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00 ], + [ 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00 ], + [ 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00 ], + [ 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00 ], + [ 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00 ], + [ 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00 ], + [ 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30 ], + [ 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00 ], + [ 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00 ], + [ 0x38, 0x6c, 0xc6, 0xd6, 0xc6, 0x6c, 0x38, 0x00 ], + [ 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00 ], + [ 0x7c, 0xc6, 0x06, 0x1c, 0x30, 0x66, 0xfe, 0x00 ], + [ 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00 ], + [ 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00 ], + [ 0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0xc6, 0x7c, 0x00 ], + [ 0x38, 0x60, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00 ], + [ 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00 ], + [ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00 ], + [ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30 ], + [ 0x06, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x06, 0x00 ], + [ 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00 ], + [ 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00 ], + [ 0x7c, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x00 ], + [ 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00 ], + [ 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00 ], + [ 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00 ], + [ 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00 ], + [ 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00 ], + [ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00 ], + [ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00 ], + [ 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3a, 0x00 ], + [ 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00 ], + [ 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00 ], + [ 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00 ], + [ 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00 ], + [ 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00 ], + [ 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00 ], + [ 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00 ], + [ 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00 ], + [ 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x7c, 0x0e ], + [ 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00 ], + [ 0x3c, 0x66, 0x30, 0x18, 0x0c, 0x66, 0x3c, 0x00 ], + [ 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00 ], + [ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 ], + [ 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00 ], + [ 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00 ], + [ 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00 ], + [ 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00 ], + [ 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00 ], + [ 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00 ], + [ 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00 ], + [ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff ], + [ 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 ], + [ 0xe0, 0x60, 0x7c, 0x66, 0x66, 0x66, 0xdc, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00 ], + [ 0x1c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00 ], + [ 0x3c, 0x66, 0x60, 0xf8, 0x60, 0x60, 0xf0, 0x00 ], + [ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8 ], + [ 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00 ], + [ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00 ], + [ 0x06, 0x00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c ], + [ 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00 ], + [ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00 ], + [ 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0x00 ], + [ 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00 ], + [ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0 ], + [ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e ], + [ 0x00, 0x00, 0xdc, 0x76, 0x60, 0x60, 0xf0, 0x00 ], + [ 0x00, 0x00, 0x7e, 0xc0, 0x7c, 0x06, 0xfc, 0x00 ], + [ 0x30, 0x30, 0xfc, 0x30, 0x30, 0x36, 0x1c, 0x00 ], + [ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00 ], + [ 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xfc ], + [ 0x00, 0x00, 0x7e, 0x4c, 0x18, 0x32, 0x7e, 0x00 ], + [ 0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 ], + [ 0x70, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x70, 0x00 ], + [ 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00 ], + [ 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x0c, 0x78 ], + [ 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00 ], + [ 0x0c, 0x18, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00 ], + [ 0x7c, 0x82, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 ], + [ 0xc6, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 ], + [ 0x30, 0x18, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 ], + [ 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 ], + [ 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0x7e, 0x0c, 0x38 ], + [ 0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00 ], + [ 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00 ], + [ 0x30, 0x18, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00 ], + [ 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00 ], + [ 0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00 ], + [ 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00 ], + [ 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00 ], + [ 0x38, 0x6c, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00 ], + [ 0x18, 0x30, 0xfe, 0xc0, 0xf8, 0xc0, 0xfe, 0x00 ], + [ 0x00, 0x00, 0x7e, 0x18, 0x7e, 0xd8, 0x7e, 0x00 ], + [ 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00 ], + [ 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0x30, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0x78, 0x84, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00 ], + [ 0x60, 0x30, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00 ], + [ 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xfc ], + [ 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x00 ], + [ 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18 ], + [ 0x38, 0x6c, 0x64, 0xf0, 0x60, 0x66, 0xfc, 0x00 ], + [ 0x66, 0x66, 0x3c, 0x7e, 0x18, 0x7e, 0x18, 0x18 ], + [ 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7 ], + [ 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0xd8, 0x70, 0x00 ], + [ 0x18, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 ], + [ 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00 ], + [ 0x0c, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 ], + [ 0x18, 0x30, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00 ], + [ 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x00 ], + [ 0x76, 0xdc, 0x00, 0xe6, 0xf6, 0xde, 0xce, 0x00 ], + [ 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00 ], + [ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00 ], + [ 0x18, 0x00, 0x18, 0x18, 0x30, 0x63, 0x3e, 0x00 ], + [ 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x00, 0x00 ], + [ 0x63, 0xe6, 0x6c, 0x7e, 0x33, 0x66, 0xcc, 0x0f ], + [ 0x63, 0xe6, 0x6c, 0x7a, 0x36, 0x6a, 0xdf, 0x06 ], + [ 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00 ], + [ 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00 ], + [ 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00 ], + [ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 ], + [ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa ], + [ 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18 ], + [ 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18 ], + [ 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00 ], + [ 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18 ], + [ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18 ], + [ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 ], + [ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00 ], + [ 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36 ], + [ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00 ], + [ 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18 ], + [ 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36 ], + [ 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36 ], + [ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18 ], + [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], + [ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff ], + [ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 ], + [ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f ], + [ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00 ], + [ 0x78, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xcc, 0x00 ], + [ 0xfe, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00 ], + [ 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x00 ], + [ 0xfe, 0xc6, 0x60, 0x30, 0x60, 0xc6, 0xfe, 0x00 ], + [ 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0xc0 ], + [ 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00 ], + [ 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x7e ], + [ 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00 ], + [ 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00 ], + [ 0x0e, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x3c, 0x00 ], + [ 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00 ], + [ 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0 ], + [ 0x1e, 0x30, 0x60, 0x7e, 0x60, 0x30, 0x1e, 0x00 ], + [ 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00 ], + [ 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00 ], + [ 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00 ], + [ 0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00 ], + [ 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00 ], + [ 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70 ], + [ 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00 ], + [ 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00 ], + [ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c ], + [ 0x6c, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00 ], + [ 0x78, 0x0c, 0x18, 0x30, 0x7c, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] + ] + @height = 8 + @[k] = v for own k, v of options + +class @ImageTextModeFontAmiga extends @ImageTextModeFont + constructor: ( options ) -> + super @width + @chars = [ + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x83, 0x83, 0x39, 0x39, 0x21, 0x21, 0x29, 0x29, 0x21, 0x21, 0x3f, 0x3f, 0x87, 0x87, 0xff, 0xff ], + [ 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0x83, 0x83, 0x99, 0x99, 0x99, 0x99, 0x83, 0x83, 0x99, 0x99, 0x99, 0x99, 0x83, 0x83, 0xff, 0xff ], + [ 0xe1, 0xe1, 0xcf, 0xcf, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xcf, 0xcf, 0xe1, 0xe1, 0xff, 0xff ], + [ 0x87, 0x87, 0x93, 0x93, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x93, 0x93, 0x87, 0x87, 0xff, 0xff ], + [ 0x81, 0x81, 0x9f, 0x9f, 0x9f, 0x9f, 0x87, 0x87, 0x9f, 0x9f, 0x9f, 0x9f, 0x81, 0x81, 0xff, 0xff ], + [ 0x81, 0x81, 0x9f, 0x9f, 0x9f, 0x9f, 0x87, 0x87, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff ], + [ 0xc3, 0xc3, 0x99, 0x99, 0x9f, 0x9f, 0x91, 0x91, 0x99, 0x99, 0x99, 0x99, 0xc1, 0xc1, 0xff, 0xff ], + [ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x9c, 0x9c, 0x99, 0x99, 0x93, 0x93, 0x87, 0x87, 0x93, 0x93, 0x99, 0x99, 0x9c, 0x9c, 0xff, 0xff ], + [ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x81, 0x81, 0xff, 0xff ], + [ 0x9c, 0x9c, 0x88, 0x88, 0x80, 0x80, 0x94, 0x94, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0xff, 0xff ], + [ 0x9c, 0x9c, 0x8c, 0x8c, 0x84, 0x84, 0x90, 0x90, 0x98, 0x98, 0x9c, 0x9c, 0x9c, 0x9c, 0xff, 0xff ], + [ 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x83, 0x83, 0x99, 0x99, 0x99, 0x99, 0x83, 0x83, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff ], + [ 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x91, 0x91, 0xc0, 0xc0, 0xff, 0xff ], + [ 0x83, 0x83, 0x99, 0x99, 0x99, 0x99, 0x83, 0x83, 0x93, 0x93, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0xc3, 0xc3, 0x99, 0x99, 0x8f, 0x8f, 0xc3, 0xc3, 0xf1, 0xf1, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x81, 0x81, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xff, 0xff ], + [ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x81, 0xc3, 0xc3, 0xe7, 0xe7, 0xff, 0xff ], + [ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x94, 0x94, 0x80, 0x80, 0x88, 0x88, 0x9c, 0x9c, 0xff, 0xff ], + [ 0x3c, 0x3c, 0x99, 0x99, 0xc3, 0xc3, 0xe7, 0xe7, 0xc3, 0xc3, 0x99, 0x99, 0x3c, 0x3c, 0xff, 0xff ], + [ 0x3c, 0x3c, 0x99, 0x99, 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xff, 0xff ], + [ 0x80, 0x80, 0xf9, 0xf9, 0xf3, 0xf3, 0xe7, 0xe7, 0xcf, 0xcf, 0x9f, 0x9f, 0x80, 0x80, 0xff, 0xff ], + [ 0xc3, 0xc3, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x3f, 0x3f, 0x9f, 0x9f, 0xcf, 0xcf, 0xe7, 0xe7, 0xf3, 0xf3, 0xf9, 0xf9, 0xfc, 0xfc, 0xff, 0xff ], + [ 0xc3, 0xc3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xf7, 0xf7, 0xe3, 0xe3, 0xc9, 0xc9, 0x9c, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00 ], + [ 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xfe, 0x6c, 0x6c, 0xfe, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x3e, 0x3e, 0x60, 0x60, 0x3c, 0x3c, 0x06, 0x06, 0x7c, 0x7c, 0x18, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0xac, 0xac, 0xd8, 0xd8, 0x36, 0x36, 0x6a, 0x6a, 0xcc, 0xcc, 0x00, 0x00 ], + [ 0x38, 0x38, 0x6c, 0x6c, 0x68, 0x68, 0x76, 0x76, 0xdc, 0xdc, 0xce, 0xce, 0x7b, 0x7b, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x3c, 0x3c, 0xff, 0xff, 0x3c, 0x3c, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x30, 0x30 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x6e, 0x6e, 0x7e, 0x7e, 0x76, 0x76, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x38, 0x38, 0x78, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x06, 0x06, 0x1c, 0x1c, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x1c, 0x1c, 0x3c, 0x3c, 0x6c, 0x6c, 0xcc, 0xcc, 0xfe, 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x60, 0x60, 0x7c, 0x7c, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x1c, 0x1c, 0x30, 0x30, 0x60, 0x60, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x06, 0x06, 0x0c, 0x0c, 0x38, 0x38, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x30, 0x30 ], + [ 0x00, 0x00, 0x06, 0x06, 0x18, 0x18, 0x60, 0x60, 0x18, 0x18, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x60, 0x60, 0x18, 0x18, 0x06, 0x06, 0x18, 0x18, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00 ], + [ 0x7c, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xd6, 0xd6, 0xde, 0xde, 0xc0, 0xc0, 0x78, 0x78, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x00, 0x00 ], + [ 0x1e, 0x1e, 0x30, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x30, 0x30, 0x1e, 0x1e, 0x00, 0x00 ], + [ 0x78, 0x78, 0x6c, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x6c, 0x78, 0x78, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x78, 0x78, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x78, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x60, 0x60, 0x6e, 0x6e, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0xc6, 0xc6, 0xcc, 0xcc, 0xd8, 0xd8, 0xf0, 0xf0, 0xd8, 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0xc6, 0xc6, 0xee, 0xee, 0xfe, 0xfe, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xf6, 0xde, 0xde, 0xce, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00 ], + [ 0x78, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0xdc, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x6c, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x70, 0x70, 0x3c, 0x3c, 0x0e, 0x0e, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x00 ], + [ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0xfe, 0xee, 0xee, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0xc3, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00 ], + [ 0xc3, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0xfe, 0xfe, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0xfe, 0xfe, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe ], + [ 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x60, 0x60, 0x60, 0x60, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x06, 0x06, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x60, 0x60, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x1c, 0x1c, 0x30, 0x30, 0x7c, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x06, 0x06, 0x3c, 0x3c ], + [ 0x60, 0x60, 0x60, 0x60, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x78, 0x78 ], + [ 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x6c, 0x6c, 0x78, 0x78, 0x6c, 0x6c, 0x66, 0x66, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xec, 0xec, 0xfe, 0xfe, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x60, 0x60, 0x60, 0x60 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x06, 0x06, 0x06, 0x06 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x60, 0x60, 0x3c, 0x3c, 0x06, 0x06, 0x7c, 0x7c, 0x00, 0x00 ], + [ 0x30, 0x30, 0x30, 0x30, 0x7c, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x1c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0xfe, 0x6c, 0x6c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x30, 0x30 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x0e, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x0e, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x70, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x70, 0x00, 0x00 ], + [ 0x72, 0x72, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x0f, 0x0f, 0x3c, 0x3c, 0xf0, 0xf0, 0xc3, 0xc3, 0x0f, 0x0f, 0x3c, 0x3c, 0xf0, 0xf0, 0x00, 0x00 ], + [ 0xcf, 0xcf, 0xe7, 0xe7, 0xc3, 0xc3, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0xf3, 0xf3, 0xe7, 0xe7, 0xc3, 0xc3, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0xe7, 0xe7, 0x99, 0x99, 0xc3, 0xc3, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0x8e, 0x8e, 0x71, 0x71, 0xc3, 0xc3, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0x99, 0x99, 0xff, 0xff, 0xc3, 0xc3, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0xe7, 0xe7, 0xdb, 0xdb, 0xc3, 0xc3, 0x99, 0x99, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff ], + [ 0xe0, 0xe0, 0xc3, 0xc3, 0xc3, 0xc3, 0x90, 0x90, 0x83, 0x83, 0x33, 0x33, 0x30, 0x30, 0xff, 0xff ], + [ 0xe1, 0xe1, 0xcf, 0xcf, 0x9f, 0x9f, 0x9f, 0x9f, 0xcf, 0xcf, 0xe1, 0xe1, 0xf3, 0xf3, 0xe7, 0xe7 ], + [ 0xcf, 0xcf, 0xe7, 0xe7, 0x81, 0x81, 0x9f, 0x9f, 0x87, 0x87, 0x9f, 0x9f, 0x81, 0x81, 0xff, 0xff ], + [ 0xf3, 0xf3, 0xe7, 0xe7, 0x81, 0x81, 0x9f, 0x9f, 0x87, 0x87, 0x9f, 0x9f, 0x81, 0x81, 0xff, 0xff ], + [ 0xe7, 0xe7, 0x99, 0x99, 0x81, 0x81, 0x9f, 0x9f, 0x87, 0x87, 0x9f, 0x9f, 0x81, 0x81, 0xff, 0xff ], + [ 0x99, 0x99, 0xff, 0xff, 0x81, 0x81, 0x9f, 0x9f, 0x87, 0x87, 0x9f, 0x9f, 0x81, 0x81, 0xff, 0xff ], + [ 0xcf, 0xcf, 0xe7, 0xe7, 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xf3, 0xf3, 0xe7, 0xe7, 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xe7, 0xe7, 0x99, 0x99, 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x99, 0x99, 0xff, 0xff, 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x87, 0x87, 0x93, 0x93, 0x99, 0x99, 0x09, 0x09, 0x99, 0x99, 0x93, 0x93, 0x87, 0x87, 0xff, 0xff ], + [ 0x8e, 0x8e, 0x31, 0x31, 0x19, 0x19, 0x09, 0x09, 0x21, 0x21, 0x31, 0x31, 0x39, 0x39, 0xff, 0xff ], + [ 0xcf, 0xcf, 0xe7, 0xe7, 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xf3, 0xf3, 0xe7, 0xe7, 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xe7, 0xe7, 0x99, 0x99, 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x8e, 0x8e, 0x71, 0x71, 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x3c, 0x3c, 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xff, 0xff, 0x39, 0x39, 0x93, 0x93, 0xc7, 0xc7, 0x93, 0x93, 0x39, 0x39, 0xff, 0xff, 0xff, 0xff ], + [ 0xc0, 0xc0, 0x99, 0x99, 0x91, 0x91, 0x81, 0x81, 0x89, 0x89, 0x99, 0x99, 0x03, 0x03, 0xff, 0xff ], + [ 0xcf, 0xcf, 0xe7, 0xe7, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xf3, 0xf3, 0xe7, 0xe7, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xe7, 0xe7, 0xdb, 0xdb, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0x99, 0x99, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xff, 0xff ], + [ 0xf9, 0xf9, 0xf7, 0xf7, 0x3c, 0x3c, 0x99, 0x99, 0xc3, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xff, 0xff ], + [ 0x3f, 0x3f, 0x3f, 0x3f, 0x03, 0x03, 0x39, 0x39, 0x03, 0x03, 0x3f, 0x3f, 0x3f, 0x3f, 0xff, 0xff ], + [ 0xc3, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x93, 0x93, 0x99, 0x99, 0x99, 0x99, 0x93, 0x93, 0x9f, 0x9f ], + [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80 ], + [ 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x00, 0x00, 0x0c, 0x0c, 0x3e, 0x3e, 0x6c, 0x6c, 0x3e, 0x3e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x1c, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x78, 0x78, 0x30, 0x30, 0x30, 0x30, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x42, 0x42, 0x3c, 0x3c, 0x66, 0x66, 0x3c, 0x3c, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0xc3, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x60, 0x60, 0x3c, 0x3c, 0x66, 0x66, 0x3c, 0x3c, 0x06, 0x06, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x81, 0x81, 0x9d, 0x9d, 0xb1, 0xb1, 0x9d, 0x9d, 0x81, 0x81, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x1c, 0x1c, 0x24, 0x24, 0x44, 0x44, 0x3c, 0x3c, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x33, 0x33, 0x66, 0x66, 0xcc, 0xcc, 0x66, 0x66, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 ], + [ 0x3e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x7e, 0x7e, 0x81, 0x81, 0xb9, 0xb9, 0xa5, 0xa5, 0xb9, 0xb9, 0xa5, 0xa5, 0x81, 0x81, 0x7e, 0x7e ], + [ 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x18, 0x18, 0x7e, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x78, 0x78, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x78, 0x78, 0x0c, 0x0c, 0x18, 0x18, 0x0c, 0x0c, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x7f, 0x60, 0x60 ], + [ 0x3e, 0x3e, 0x7a, 0x7a, 0x7a, 0x7a, 0x3a, 0x3a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x30 ], + [ 0x30, 0x30, 0x70, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], + [ 0x38, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xcc, 0xcc, 0x66, 0x66, 0x33, 0x33, 0x66, 0x66, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00 ], + [ 0x40, 0x40, 0xc6, 0xc6, 0x4c, 0x4c, 0x58, 0x58, 0x32, 0x32, 0x66, 0x66, 0xcf, 0xcf, 0x02, 0x02 ], + [ 0x40, 0x40, 0xc6, 0xc6, 0x4c, 0x4c, 0x58, 0x58, 0x3e, 0x3e, 0x62, 0x62, 0xc4, 0xc4, 0x0e, 0x0e ], + [ 0xc0, 0xc0, 0x23, 0x23, 0x66, 0x66, 0x2c, 0x2c, 0xd9, 0xd9, 0x33, 0x33, 0x67, 0x67, 0x01, 0x01 ], + [ 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x71, 0x71, 0x8e, 0x8e, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x66, 0x66, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x18, 0x18, 0x24, 0x24, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x1f, 0x1f, 0x3c, 0x3c, 0x3c, 0x3c, 0x6f, 0x6f, 0x7c, 0x7c, 0xcc, 0xcc, 0xcf, 0xcf, 0x00, 0x00 ], + [ 0x1e, 0x1e, 0x30, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x30, 0x1e, 0x1e, 0x0c, 0x0c, 0x18, 0x18 ], + [ 0x30, 0x30, 0x18, 0x18, 0x7e, 0x7e, 0x60, 0x60, 0x78, 0x78, 0x60, 0x60, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x7e, 0x7e, 0x60, 0x60, 0x78, 0x78, 0x60, 0x60, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x7e, 0x7e, 0x60, 0x60, 0x78, 0x78, 0x60, 0x60, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x66, 0x66, 0x00, 0x00, 0x7e, 0x7e, 0x60, 0x60, 0x78, 0x78, 0x60, 0x60, 0x7e, 0x7e, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x66, 0x66, 0x00, 0x00, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x78, 0x78, 0x6c, 0x6c, 0x66, 0x66, 0xf6, 0xf6, 0x66, 0x66, 0x6c, 0x6c, 0x78, 0x78, 0x00, 0x00 ], + [ 0x71, 0x71, 0xce, 0xce, 0xe6, 0xe6, 0xf6, 0xf6, 0xde, 0xde, 0xce, 0xce, 0xc6, 0xc6, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x71, 0x71, 0x8e, 0x8e, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0xc3, 0xc3, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00 ], + [ 0x3f, 0x3f, 0x66, 0x66, 0x6e, 0x6e, 0x7e, 0x7e, 0x76, 0x76, 0x66, 0x66, 0xfc, 0xfc, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x24, 0x24, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x06, 0x06, 0x08, 0x08, 0xc3, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00 ], + [ 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc, 0xc6, 0xc6, 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00 ], + [ 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x6c, 0x60, 0x60 ], + [ 0x30, 0x30, 0x18, 0x18, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x71, 0x71, 0x8e, 0x8e, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x66, 0x66, 0x00, 0x00, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x18, 0x18, 0x24, 0x24, 0x3c, 0x3c, 0x06, 0x06, 0x3e, 0x3e, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x1b, 0x1b, 0x7f, 0x7f, 0xd8, 0xd8, 0x77, 0x77, 0x00, 0x00 ], + [ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x3c, 0x3c, 0x18, 0x18 ], + [ 0x30, 0x30, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x60, 0x60, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x60, 0x60, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x60, 0x60, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x66, 0x66, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x7e, 0x7e, 0x60, 0x60, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00 ], + [ 0x60, 0x60, 0xfc, 0xfc, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x71, 0x71, 0x8e, 0x8e, 0x00, 0x00, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00 ], + [ 0x30, 0x30, 0x18, 0x18, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x71, 0x71, 0x8e, 0x8e, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x3c, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x00, 0x00 ], + [ 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0x02, 0x02, 0x7c, 0x7c, 0xce, 0xce, 0xd6, 0xd6, 0xe6, 0xe6, 0x7c, 0x7c, 0x80, 0x80 ], + [ 0x30, 0x30, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x18, 0x18, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x3e, 0x00, 0x00 ], + [ 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x30, 0x30 ], + [ 0x60, 0x60, 0x60, 0x60, 0x7c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x7c, 0x60, 0x60, 0x60, 0x60 ], + [ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x18, 0x30, 0x30 ] + ] + @height = 16 + @[k] = v for own k, v of options diff --git a/16col/idf.coffee b/16col/idf.coffee new file mode 100644 index 0000000..0ee5ead --- /dev/null +++ b/16col/idf.coffee @@ -0,0 +1,55 @@ +class @ImageTextModeIDF extends @ImageTextMode + + constructor: ( options ) -> + super + @header = { x0: 0, x1: 0, y0: 0, y1: 0 } + this[k] = v for own k, v of options + + parse: ( content ) -> + headerData = content.substr( 0, 12 ) + if headerData.length isnt 12 || !headerData.match( '^\x041.4' ) + throw new Error( 'File is not an IDF' ) + + @header.x0 = @unpackShort( headerData.substr( 4, 2 ) ) + @header.y0 = @unpackShort( headerData.substr( 6, 2 ) ) + @header.x1 = @unpackShort( headerData.substr( 8, 2 ) ) + @header.y1 = @unpackShort( headerData.substr( 10, 2 ) ) + + eodata = content.length - 48 - 4096 + + if content.substr( content.length - 128, 5 ) == 'SAUCE' + eodata -= 128 + + @parseFontData( content.substr( eodata, 4096 ) ) + @parsePaletteData( content.substr( eodata + 4096, 48 ) ) + + y = 0 + x = 0 + @screen[ y ] = [] + offset = 12 + + while offset < eodata + buffer = content.substr( offset, 2 ) + info = @unpackShort( buffer ) + offset += 2 + len = 1 + + if info == 1 + len = @unpackShort( content.substr( offset, 2 ) ) & 255 + offset += 2 + buffer = content.substr( offset, 2 ) + offset += 2 + + ch = buffer.substr( 0, 1 ) + attr = @getByteAt( buffer, 1 ) + + for i in [ 1 .. len ] + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x > @header.x1 + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + diff --git a/16col/imgtxtmode.coffee b/16col/imgtxtmode.coffee new file mode 100644 index 0000000..c109dc0 --- /dev/null +++ b/16col/imgtxtmode.coffee @@ -0,0 +1,115 @@ +class @ImageTextMode + + @VERSION = '0.01' + + constructor: ( options ) -> + @screen = [] + @palette = new ImageTextModePaletteVGA() + @font = new ImageTextModeFont8x16() + @[k] = v for own k, v of options + + parseUrl: ( url ) -> + req = new XMLHttpRequest() + req.open 'GET', url, false + req.overrideMimeType 'text/plain; charset=x-user-defined' + req.send null + content = if req.status is 200 or req.status is 0 then req.responseText else '' + @parse content + + unpackShort: ( data ) -> + shrt = ( @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 0 ) + if shrt < 0 + shrt += 65536 + shrt + + unpackLong: ( data ) -> + lng = ((( @getByteAt( data, 0 ) << 8 ) + @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 2 ) << 8 ) + @getByteAt( data, 3 ) + if lng < 0 + lng += 4294967296 + lng + + getByteAt: ( data, offset ) -> + data.charCodeAt( offset ) & 0xFF + +# could we replace this with math.max ? Not worth it,called once per view +# we COULD, but we'd do some crap like "Math.max.apply(null,blah) and that's not readable" + getWidth: -> + max = 0 + for y in [ 0 .. @screen.length - 1 ] + max = @screen[ y ].length if @screen[ y ]? && @screen[ y ].length > max + max + + getHeight: -> + @screen.length + + parsePaletteData: ( data ) -> + colors = [] + for i in [ 0 .. 45 ] by 3 + r = @getByteAt( data, i ) + r = r << 2 | r >> 4 + g = @getByteAt( data, i + 1 ) + g = g << 2 | g >> 4 + b = @getByteAt( data, i + 2 ) + b = b << 2 | b >> 4 + colors.push [ r, g, b ] + + @palette = new ImageTextModePalette( colors: colors ) + + parseFontData: ( data, height = 16 ) -> + chars = [] + for i in [ 0 ... data.length / height ] + chr = [] + for j in [ 0 ... height ] + chr.push @getByteAt( data, i * height + j ) + chars.push chr + @font = new ImageTextModeFont( { chars: chars, height: height } ) + +# the majority of time is spent in this routine +# list comprehension seems to speed up from 1.8 seconds to 1.29 seconds from first comprehension / cleanup? + + renderCanvas: ( canvasElem ) -> + w = @getWidth() * @font.width + h = @getHeight() * @font.height + + canvas = document.createElement 'canvas' + canvas.setAttribute 'width', w + canvas.setAttribute 'height', h + ctx = canvas.getContext '2d' + + for cy in [ 0 ... @screen.length ] + if @screen[ cy ]? + for cx in [ 0 ... @screen[ cy ].length ] + pixel = @screen[ cy ][ cx ] + curfillstyle = null + if pixel? + if pixel.attr? + fg = pixel.attr & 15 + bg = ( pixel.attr & 240 ) >> 4 + else + fg = pixel.fg + bg = pixel.bg + + px = cx * @font.width + py = cy * @font.height + + ctx.fillStyle = @palette.toRgbaString( @palette.colors[ bg ] ) + ctx.fillRect px, py, @font.width, @font.height + + ctx.fillStyle = @palette.toRgbaString( @palette.colors[ fg ] ) + chr = @font.chars[ pixel.ch.charCodeAt( 0 ) & 0xff ] + i = 0 + for line in chr + ctx.fillRect px + j, py + i, 1, 1 for j in [ 0 ... @font.width ] when line & (1 << @font.width - 1 - j ) + i += 1 + + canvasElem.setAttribute 'width', w + canvasElem.setAttribute 'height', h + ctx = canvasElem.getContext '2d' + ctx.drawImage canvas, 0, 0 + + toBinaryArray: (str) -> + buf = new ArrayBuffer(str.length * 2) # 2 bytes for each char + bufView = new Uint8Array(buf) + bufView[i] = str.charCodeAt(i) for i in [0...str.length] + buf + diff --git a/16col/pallette.coffee b/16col/pallette.coffee new file mode 100644 index 0000000..f3d738d --- /dev/null +++ b/16col/pallette.coffee @@ -0,0 +1,62 @@ +class @ImageTextModePalette + + constructor: ( options ) -> + @colors = [] + @[k] = v for own k, v of options + + toRgbaString: ( color ) -> + return 'rgba(' + color.join( ',' ) + ',1)'; + +# getting a "cannot call super outside an instance method" error here - +# the resulting code produced does not end up using the super/parent bit +# or at least it doesn't produce bugs in the result if it is not here. +# calling the constructor without super works, and with super the difference is +# ImageTextModePaletteVGA.__super__.constructor.apply(this, arguments); +# is placed inside the constructor. I believe the end result, based on how +# this is used, is identical. +# I am not seeing this pattern (the 'super by itself') being used or referenced +# - instead I am seeting very different patterns using super to reference +# complete items. (referenced meaning "in books, searches, or coffescript +# documentation") + +class @ImageTextModePaletteVGA extends @ImageTextModePalette + constructor: (options) -> + @colors = [ + [ 0x00, 0x00, 0x00 ], + [ 0x00, 0x00, 0xaa ], + [ 0x00, 0xaa, 0x00 ], + [ 0x00, 0xaa, 0xaa ], + [ 0xaa, 0x00, 0x00 ], + [ 0xaa, 0x00, 0xaa ], + [ 0xaa, 0x55, 0x00 ], + [ 0xaa, 0xaa, 0xaa ], + [ 0x55, 0x55, 0x55 ], + [ 0x55, 0x55, 0xff ], + [ 0x55, 0xff, 0x55 ], + [ 0x55, 0xff, 0xff ], + [ 0xff, 0x55, 0x55 ], + [ 0xff, 0x55, 0xff ], + [ 0xff, 0xff, 0x55 ], + [ 0xff, 0xff, 0xff ] + ] + +class @ImageTextModePaletteANSI extends @ImageTextModePalette + constructor: (options) -> + @colors = [ + [ 0x00, 0x00, 0x00 ], + [ 0xaa, 0x00, 0x00 ], + [ 0x00, 0xaa, 0x00 ], + [ 0xaa, 0x55, 0x00 ], + [ 0x00, 0x00, 0xaa ], + [ 0xaa, 0x00, 0xaa ], + [ 0x00, 0xaa, 0xaa ], + [ 0xaa, 0xaa, 0xaa ], + [ 0x55, 0x55, 0x55 ], + [ 0xff, 0x55, 0x55 ], + [ 0x55, 0xff, 0x55 ], + [ 0xff, 0xff, 0x55 ], + [ 0x55, 0x55, 0xff ], + [ 0xff, 0x55, 0xff ], + [ 0x55, 0xff, 0xff ], + [ 0xff, 0xff, 0xff ] + ] \ No newline at end of file diff --git a/16col/pcboard.coffee b/16col/pcboard.coffee new file mode 100644 index 0000000..e1e370d --- /dev/null +++ b/16col/pcboard.coffee @@ -0,0 +1,67 @@ + +class @ImageTextModePCBoard extends @ImageTextMode + + constructor: ( options ) -> + super + @tabstop = 8 + @linewrap = 80 + @codes = { POFF: '', WAIT: '' } + this[k] = v for own k, v of options + + parse: ( content ) -> + @screen = [] + @state = 0 + @x = 0 + @y = 0 + @attr = 7 + + for key, val of @codes + code = new RegExp '@' + key + '@', 'g' + content.replace code, val + + content = content.split( '' ) + while ch = content.shift() + if @state is 0 + switch ch + when "\x1a" then @state = 2 + when '@' then @state = 1 + when "\n" + @x = 0 + @y++ + when "\r" then break + when "\t" + i = ( @x + 1 ) % @tabstop + @putpixel ' ' while i-- > 0 + else + @putpixel ch + else if @state is 1 + if ch is 'X' + @attr = ( parseInt( content.shift(), 16 ) << 4 ) + parseInt( content.shift(), 16 ) + else if ch + content[ 0..2 ].join( '' ) is 'CLS@' + content.shift() for [ 1 .. 3 ] + @screen = [] + else if ch + content[ 0..2 ].join( '' ) is 'POS:' + content.shift() for [ 1 .. 3 ] + @x = content.shift() + @x += content.shift() if content[ 0 ] isnt '@' + @x-- + + content.shift() + else + @putpixel '@' + @putpixel ch + + @state = 0 + else if @state is 2 + break + else + @state = 0 + + putpixel: ( ch ) -> + @screen[ @y ] = [] if !@screen[ @y ]? + @screen[ @y ][ @x ] = { ch: ch, attr: @attr } + + if ++@x >= @linewrap + @x = 0 + @y++ + diff --git a/16col/sauce.coffee b/16col/sauce.coffee new file mode 100644 index 0000000..dad1590 --- /dev/null +++ b/16col/sauce.coffee @@ -0,0 +1,56 @@ +class @ImageTextModeSAUCE + + parseUrl: ( url ) -> + req = new XMLHttpRequest() + req.open 'GET', url, false + req.overrideMimeType 'text/plain; charset=x-user-defined' + req.send null + content = if req.status is 200 or req.status is 0 then req.responseText else '' + @parse content + + parse: ( content ) -> + sauceMarker = content.length - 128; + return false if content.substr( sauceMarker, 5 ) isnt 'SAUCE' + @id = 'SAUCE' + @version = content.substr( sauceMarker + 5, 2 ) + @title = content.substr( sauceMarker + 7, 35 ) + @author = content.substr( sauceMarker + 42, 20 ) + @group = content.substr( sauceMarker + 62, 20 ) + @date = content.substr( sauceMarker + 82, 8 ) + @fileSize = @unpackLong content.substr( sauceMarker + 90, 4 ) + @dataType = @getByteAt content.substr( sauceMarker + 94, 1 ) + @fileType = @getByteAt content.substr( sauceMarker + 95, 1 ) + @tinfo1 = @unpackShort content.substr( sauceMarker + 96, 2 ) + @tinfo2 = @unpackShort content.substr( sauceMarker + 98, 2 ) + @tinfo3 = @unpackShort content.substr( sauceMarker + 100, 2 ) + @tinfo4 = @unpackShort content.substr( sauceMarker + 102, 2 ) + @commentCount = @getByteAt content.substr( sauceMarker + 104, 1 ) + @flags = @getByteAt content.substr( sauceMarker + 105, 1 ) + @filler = content.substr( sauceMarker + 106, 22 ) + + commentMarker = sauceMarker - 5 - @commentCount * 64 + if @commentCount > 0 and content.substr( commentMarker, 5 ) is 'COMNT' + commentMarker += 5 + @comments = [] + i = @commentCount + while i-- > 0 + @comments.push content.substr( commentMarker, 64 ) + commentMarker += 64 + + return true + + unpackLong: ( data ) -> + lng = ((( @getByteAt( data, 3 ) << 8 ) + @getByteAt( data, 2 ) << 8 ) + @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 0 ) + if lng < 0 + lng += 4294967296 + return lng; + + unpackShort: ( data ) -> + shrt = ( @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 0 ) + if shrt < 0 + shrt += 65536 + return shrt + + getByteAt: ( data, offset ) -> + return data.charCodeAt( offset ) & 0xFF + diff --git a/16col/tundra.coffee b/16col/tundra.coffee new file mode 100644 index 0000000..b1960b7 --- /dev/null +++ b/16col/tundra.coffee @@ -0,0 +1,70 @@ + +class @ImageTextModeTundra extends @ImageTextMode + + constructor: ( options ) -> + super + this[k] = v for own k, v of options + + parse: ( content ) -> + colors = [ [ 0, 0, 0 ] ] + palidx = 1 + x = 0 + y = 0 + fg = 0 + bg = 0 + + @screen[ y ] = [] + content = content.substr( 8 ).split( '' ) + while command = content.shift() + break if command == "\x1a" + command = command.charCodeAt( 0 ) + + if command is 1 + y = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + x = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + @screen[ y ] = [] if !@screen[ y ]? + continue + + ch = null + + if command is 2 + ch = content.shift() + rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + fg = palidx++ + colors.push [ + ( rgb >> 16 ) & 0x000000ff, + ( rgb >> 8 ) & 0x000000ff, + rgb & 0x000000ff + ] + else if command is 4 + ch = content.shift() + rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + bg = palidx++ + colors.push [ + ( rgb >> 16 ) & 0x000000ff, + ( rgb >> 8 ) & 0x000000ff, + rgb & 0x000000ff + ] + else if command is 6 + ch = content.shift() + fg = palidx++ + bg = palidx++ + for [ 0 .. 1 ] + rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + colors.push [ + ( rgb >> 16 ) & 0x000000ff, + ( rgb >> 8 ) & 0x000000ff, + rgb & 0x000000ff + ] + + ch = String.fromCharCode( command ) unless ch? + + @screen[ y ][ x ] = { 'ch': ch, 'fg': fg, 'bg': bg } + x++ + if x == 80 + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + @palette = new ImageTextModePalette( { colors: colors } ) diff --git a/16col/xbin.coffee b/16col/xbin.coffee new file mode 100644 index 0000000..4faa076 --- /dev/null +++ b/16col/xbin.coffee @@ -0,0 +1,117 @@ + +class @ImageTextModeXBin extends @ImageTextMode + + # Header constants + PALETTE = 1 + FONT = 2 + COMPRESSED = 4 + NON_BLINK = 8 + FIVETWELVE_CHARS = 16 + + # Compression type constants + NO_COMPRESSION = 0 + CHARACTER_COMPRESSION = 64 + ATTRIBUTE_COMPRESSION = 128 + FULL_COMPRESSION = 192 + + # Compression byte constants + COMPRESSION_TYPE = 192 + COMPRESSION_COUNTER = 63 + + constructor: ( options ) -> + super + @header = { width: 0, height: 0, fontisze: 0, flags: 0 } + this[k] = v for own k, v of options + + parse: ( content ) -> + @screen = [] + headerData = content.substr( 0, 11 ) + if headerData.length isnt 11 || !headerData.match( '^XBIN\x1a' ) + throw new Error( 'File is not an XBin' ) + + @header.width = @unpackShort( headerData.substr( 5, 2 ) ) + @header.height = @unpackShort( headerData.substr( 7, 2 ) ) + @header.fontsize = @getByteAt( headerData.substr( 9, 1 ) ) + @header.flags = @getByteAt( headerData.substr( 10, 1 ) ) + offset = 11 + + if @header.flags & PALETTE + @parsePaletteData( content.substr( offset, 48 ) ); + offset += 48 + + if @header.flags & FONT + fontlength = @header.fontsize + if @header.flags & FIVETWELVE_CHARS + fontlength *= 512 + else + fontlength *= 256 + @parseFontData( content.substr( offset, fontlength ), @header.fontsize ); + offset += fontlength + + if @header.flags & COMPRESSED + @_parse_compressed( content.substr( offset ) ) + else + @_parse_uncompressed( content.substr( offset ) ) + + _parse_compressed: ( data ) -> + x = 0 + y = 0 + @screen[ y ] = [] + + data = data.split( '' ) + while info = data.shift() + info = @getByteAt( info, 0 ) + break if info == 26 + + type = info & COMPRESSION_TYPE + counter = ( info & COMPRESSION_COUNTER ) + 1 + + ch = null + attr = null + + while counter-- > 0 + switch type + when NO_COMPRESSION + ch = data.shift() + attr = data.shift() + when CHARACTER_COMPRESSION + ch = data.shift() if !ch? + attr = data.shift() + when ATTRIBUTE_COMPRESSION + attr = data.shift() if !attr? + ch = data.shift() + else + ch = data.shift() if !ch? + attr = data.shift() if !attr? + + @screen[ y ][ x ] = { ch: ch, attr: @getByteAt( attr, 0 ) } + + x++ + if x == @header.width + x = 0 + y++ + break if y == @header.height + @screen[ y ] = [] if !@screen[ y ]? + + _parse_uncompressed: ( data ) -> + x = 0 + y = 0 + @screen[ y ] = [] + + for i in [ 0 .. data.length - 2 ] by 2 + ch = data.substr( i, 1 ) + break if ch == "\x1a" + attr = @getByteAt( data, i + 1 ) + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x == @header.width + x = 0 + y++ + break if y == @header.height + @screen[ y ] = [] if !@screen[ y ]? + + getWidth: -> + return @header.width + + getHeight: -> + return @header.height diff --git a/Cakefile b/Cakefile new file mode 100644 index 0000000..b49d866 --- /dev/null +++ b/Cakefile @@ -0,0 +1,47 @@ +fs = require 'fs' +option '-o', '--output [dir]', 'dir for compiled code' + +task 'watch', 'watch current dir', (options) -> + {spawn} = require 'child_process' + args = ['-w','-c'] + if options.output + args = args.concat ['./'] + + process.chdir __originalDirname + coffee = spawn 'coffee', args + coffee.stderr.on 'data', (data) -> + process.stderr.write data.toString() + coffee.stdout.on 'data', (data) -> + console.log data.toString() + +source = [ + '16col/imgtxtmode.coffee', + '16col/ansi.coffee', + '16col/bin.coffee', + '16col/idf.coffee', + '16col/adf.coffee', + '16col/sauce.coffee', + '16col/tundra.coffee', + '16col/pcboard.coffee', + '16col/avatar.coffee', + '16col/xbin.coffee', + '16col/pallette.coffee', + '16col/fonts.coffee' +] + +task 'build', 'Build merged file for production', (options) -> + {exec} = require 'child_process' + content = [] + + for file, index in source then do (file, index) -> + fs.readFile file, 'utf8', (err, fileContents) -> + throw err if err + content[index] = fileContents + if index == source.length - 1 + coffee = content.join('\n') + fs.writeFile 'textmode.coffee', coffee, 'utf8', (err) -> + throw err if err + command = 'coffee --compile textmode.coffee' + exec command, (err, stdout, stderr) -> + throw err if err + console.log stdout + stderr \ No newline at end of file diff --git a/textmode.coffee b/textmode.coffee index 4949775..2d62724 100644 --- a/textmode.coffee +++ b/textmode.coffee @@ -1,3 +1,426 @@ +class @ImageTextMode + + @VERSION = '0.01' + + constructor: ( options ) -> + @screen = [] + @palette = new ImageTextModePaletteVGA() + @font = new ImageTextModeFont8x16() + @[k] = v for own k, v of options + + parseUrl: ( url ) -> + req = new XMLHttpRequest() + req.open 'GET', url, false + req.overrideMimeType 'text/plain; charset=x-user-defined' + req.send null + content = if req.status is 200 or req.status is 0 then req.responseText else '' + @parse content + + unpackShort: ( data ) -> + shrt = ( @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 0 ) + if shrt < 0 + shrt += 65536 + shrt + + unpackLong: ( data ) -> + lng = ((( @getByteAt( data, 0 ) << 8 ) + @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 2 ) << 8 ) + @getByteAt( data, 3 ) + if lng < 0 + lng += 4294967296 + lng + + getByteAt: ( data, offset ) -> + data.charCodeAt( offset ) & 0xFF + +# could we replace this with math.max ? Not worth it,called once per view +# we COULD, but we'd do some crap like "Math.max.apply(null,blah) and that's not readable" + getWidth: -> + max = 0 + for y in [ 0 .. @screen.length - 1 ] + max = @screen[ y ].length if @screen[ y ]? && @screen[ y ].length > max + max + + getHeight: -> + @screen.length + + parsePaletteData: ( data ) -> + colors = [] + for i in [ 0 .. 45 ] by 3 + r = @getByteAt( data, i ) + r = r << 2 | r >> 4 + g = @getByteAt( data, i + 1 ) + g = g << 2 | g >> 4 + b = @getByteAt( data, i + 2 ) + b = b << 2 | b >> 4 + colors.push [ r, g, b ] + + @palette = new ImageTextModePalette( colors: colors ) + + parseFontData: ( data, height = 16 ) -> + chars = [] + for i in [ 0 ... data.length / height ] + chr = [] + for j in [ 0 ... height ] + chr.push @getByteAt( data, i * height + j ) + chars.push chr + @font = new ImageTextModeFont( { chars: chars, height: height } ) + +# the majority of time is spent in this routine +# list comprehension seems to speed up from 1.8 seconds to 1.29 seconds from first comprehension / cleanup? + + renderCanvas: ( canvasElem ) -> + w = @getWidth() * @font.width + h = @getHeight() * @font.height + + canvas = document.createElement 'canvas' + canvas.setAttribute 'width', w + canvas.setAttribute 'height', h + ctx = canvas.getContext '2d' + + for cy in [ 0 ... @screen.length ] + if @screen[ cy ]? + for cx in [ 0 ... @screen[ cy ].length ] + pixel = @screen[ cy ][ cx ] + curfillstyle = null + if pixel? + if pixel.attr? + fg = pixel.attr & 15 + bg = ( pixel.attr & 240 ) >> 4 + else + fg = pixel.fg + bg = pixel.bg + + px = cx * @font.width + py = cy * @font.height + + ctx.fillStyle = @palette.toRgbaString( @palette.colors[ bg ] ) + ctx.fillRect px, py, @font.width, @font.height + + ctx.fillStyle = @palette.toRgbaString( @palette.colors[ fg ] ) + chr = @font.chars[ pixel.ch.charCodeAt( 0 ) & 0xff ] + i = 0 + for line in chr + ctx.fillRect px + j, py + i, 1, 1 for j in [ 0 ... @font.width ] when line & (1 << @font.width - 1 - j ) + i += 1 + + canvasElem.setAttribute 'width', w + canvasElem.setAttribute 'height', h + ctx = canvasElem.getContext '2d' + ctx.drawImage canvas, 0, 0 + + toBinaryArray: (str) -> + buf = new ArrayBuffer(str.length * 2) # 2 bytes for each char + bufView = new Uint8Array(buf) + bufView[i] = str.charCodeAt(i) for i in [0...str.length] + buf + + + +class @ImageTextModeANSI extends @ImageTextMode + constructor: ( options ) -> + super @screen + super @font + @palette = new ImageTextModePaletteANSI + @tabstop = 8 + @linewrap = 80 + @[k] = v for own k, v of options + + ANSI_ESC = String.fromCharCode(0x1b) + ANSI_CSI = ANSI_ESC + '[' + ANSI_TEXT_PROP = 'm' + ANSI_RESET = '0' + ANSI_FG = '3' + ANSI_BG = '4' + ANSI_FG_INTENSE = '9' + ANSI_BG_INTENSE = '10' + ANSI_CUR_DOWN = 'B' + ANSI_SEP = ';' + ANSI_RETURN = 'A' + +# not going to mess with this for now, as I think it is the 'write' code +# for the actual ansi editor. That would be bad to mess up. +# did redo the for loops to read nicer tho. + + write: -> + content = "#{ ANSI_CSI }2J" # initiate document + for y in [0...@screen.length] + content += "\n" if !@screen[y]? + continue if !@screen[y]? + for x in [0...@getWidth()] + pixel = @screen[y][x] + if !pixel? + pixel = { ch: ' ', attr: 7 } + attr = @gen_args(pixel.attr) + if (attr != prevattr) + content += "#{ANSI_CSI}0;#{attr}#{ANSI_TEXT_PROP}" + prevattr = attr + content += if pixel.ch? then pixel.ch else ' ' + max_x = x + content += "#{ ANSI_CSI }0m" + @toBinaryArray(content) + + gen_args: ( attr ) -> + fg = 30 + ( attr & 7 ) + bg = 40 + ( ( attr & 112 ) >> 4) + bl = if attr & 128 then 5 else '' + intense = if attr & 8 then 1 else '' + +# um why do we make this attrs variable and not use it? + + attrs = a for a in [fg, bg, bl, intense] when a != '' + return [fg, bg, bl, intense].join(";") + + parse: ( content ) -> + @screen = [] + @state = 0 + @x = 0 + @y = 0 + @save_x = 0 + @save_y = 0 + @attr = 7 + @argbuf = '' + + content = content.split( '' ) + while ch = content.shift() + if @state is 0 + switch ch + when "\x1a" then @state = 3 + when "\x1b" then @state = 1 + when "\n" + @x = 0 + @y++ + when "\r" then break + when "\t" + i = ( @x + 1 ) % @tabstop + @putpixel ' ' while i-- > 0 + else + @putpixel ch + + else if @state is 1 + if ch isnt "[" + @putpixel "\x1b" + @putpixel "[" + @state = 0 + else + @state = 2 + + else if @state is 2 + if ch.match( '[A-Za-z]' ) + args = ( parseInt( i ) for i in @argbuf.split ';' ) + + switch ch + when "m" + for arg in args + if arg is 0 + @attr = 7 + else if arg is 1 + @attr |= 8 + else if arg is 5 + @attr |= 128 + else if 30 <= arg <= 37 + @attr &= 248 + @attr |= ( arg - 30 ) + else if 40 <= arg <= 47 + @attr &= 143 + @attr |= ( arg - 40 ) << 4 + + when "H", "f" + @y = ( args[ 0 ] or 1 ) - 1 + @x = ( args[ 1 ] or 1 ) - 1 + @y = 0 if @y < 0 + @x = 0 if @x < 0 + when "A" + @y -= args[ 0 ] or 1 + @y = 0 if @y < 0 + when "B" + @y += args[ 0 ] or 1 + when "C" + @x += args[ 0 ] or 1 + when "D" + @x -= args[ 0 ] or 1 + @x = 0 if @x < 0 + when "E" + @y += args[ 0 ] or 1 + @x = 0 + when "F" + @y -= args[ 0 ] or 1 + @y = 0 if @y > 0 + @x = 0 + when "G" + @x = ( args[ 0 ] or 1 ) - 1 + when "s" + @save_x = @x + @save_y = @y + when "u" + @x = @save_x + @y = @save_y + when "J" + if args.length is 0 or args[ 0 ] is 0 + @screen[ i ] = null for i in [ @y + 1 .. screen.length - 1 ] + @screen[ @y ][ i ] = null for i in [ @x .. screen[ @y ].length - 1 ] + else if args[ 0 ] is 1 + @screen[ i ] = null for i in [ 0 .. @y - 1 ] + @screen[ @y ][ i ] = null for i in [ 0 .. @x ] + else if args[ 0 ] is 2 + @x = 0 + @y = 0 + @screen = [] + when "K" + if args.length is 0 or args[ 0 ] is 0 + @screen[ @y ][ i ] = null for i in [ @x .. @screen[ @y ].length - 1 ] + else if args[ 0 ] is 1 + @screen[ @y ][ i ] = null for i in [ 0 .. @x ] + else if args[ 0 ] is 2 + @screen[ @y ] = null + + @argbuf = '' + @state = 0 + + else + @argbuf += ch + + else if @state is 3 + break + + else + @state = 0 + + + putpixel: ( ch ) -> + @screen[ @y ] = [] if !@screen[ @y ]? + @screen[ @y ][ @x ] = { ch: ch, attr: @attr } + + if ++@x >= @linewrap + @x = 0 + @y++ + + +class @ImageTextModeBin extends @ImageTextMode + + constructor: ( options ) -> + super + @linewrap = 160 + this[k] = v for own k, v of options + + parse: ( content ) -> + x = 0 + y = 0 + @screen[ y ] = [] + + for i in [ 0 .. content.length - 2 ] by 2 + ch = content.substr( i, 1 ) + break if ch == "\x1a" + attr = @getByteAt( content, i + 1 ) + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x == @linewrap + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + + +class @ImageTextModeIDF extends @ImageTextMode + + constructor: ( options ) -> + super + @header = { x0: 0, x1: 0, y0: 0, y1: 0 } + this[k] = v for own k, v of options + + parse: ( content ) -> + headerData = content.substr( 0, 12 ) + if headerData.length isnt 12 || !headerData.match( '^\x041.4' ) + throw new Error( 'File is not an IDF' ) + + @header.x0 = @unpackShort( headerData.substr( 4, 2 ) ) + @header.y0 = @unpackShort( headerData.substr( 6, 2 ) ) + @header.x1 = @unpackShort( headerData.substr( 8, 2 ) ) + @header.y1 = @unpackShort( headerData.substr( 10, 2 ) ) + + eodata = content.length - 48 - 4096 + + if content.substr( content.length - 128, 5 ) == 'SAUCE' + eodata -= 128 + + @parseFontData( content.substr( eodata, 4096 ) ) + @parsePaletteData( content.substr( eodata + 4096, 48 ) ) + + y = 0 + x = 0 + @screen[ y ] = [] + offset = 12 + + while offset < eodata + buffer = content.substr( offset, 2 ) + info = @unpackShort( buffer ) + offset += 2 + len = 1 + + if info == 1 + len = @unpackShort( content.substr( offset, 2 ) ) & 255 + offset += 2 + buffer = content.substr( offset, 2 ) + offset += 2 + + ch = buffer.substr( 0, 1 ) + attr = @getByteAt( buffer, 1 ) + + for i in [ 1 .. len ] + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x > @header.x1 + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + + +class @ImageTextModeADF extends @ImageTextMode + + COLOR_INDEX = [ 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63 ] + + constructor: ( options ) -> + super + @header = { version: 0 } + this[k] = v for own k, v of options + + parse: ( content ) -> + @header.version = @getByteAt( content, 0 ) + @parsePaletteData( content.substr( 1, 192 ) ) + @parseFontData( content.substr( 193, 4096 ) ) + + x = 0 + y = 0 + @screen[ y ] = [] + + for i in [ 4289 .. content.length - 2 ] by 2 + ch = content.substr( i, 1 ) + break if ch == "\x1a" + attr = @getByteAt( content, i + 1 ) + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x == 80 + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + + parsePaletteData: ( data ) -> + colors = [] + for i in COLOR_INDEX + j = i * 3 + r = @getByteAt( data, j ) + r = r << 2 | r >> 4 + g = @getByteAt( data, j + 1 ) + g = g << 2 | g >> 4 + b = @getByteAt( data, j + 2 ) + b = b << 2 | b >> 4 + colors.push [ r, g, b ] + + @palette = new ImageTextModePalette( { colors: colors } ) + class @ImageTextModeSAUCE parseUrl: ( url ) -> @@ -54,6 +477,333 @@ class @ImageTextModeSAUCE getByteAt: ( data, offset ) -> return data.charCodeAt( offset ) & 0xFF + + +class @ImageTextModeTundra extends @ImageTextMode + + constructor: ( options ) -> + super + this[k] = v for own k, v of options + + parse: ( content ) -> + colors = [ [ 0, 0, 0 ] ] + palidx = 1 + x = 0 + y = 0 + fg = 0 + bg = 0 + + @screen[ y ] = [] + content = content.substr( 8 ).split( '' ) + while command = content.shift() + break if command == "\x1a" + command = command.charCodeAt( 0 ) + + if command is 1 + y = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + x = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + @screen[ y ] = [] if !@screen[ y ]? + continue + + ch = null + + if command is 2 + ch = content.shift() + rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + fg = palidx++ + colors.push [ + ( rgb >> 16 ) & 0x000000ff, + ( rgb >> 8 ) & 0x000000ff, + rgb & 0x000000ff + ] + else if command is 4 + ch = content.shift() + rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + bg = palidx++ + colors.push [ + ( rgb >> 16 ) & 0x000000ff, + ( rgb >> 8 ) & 0x000000ff, + rgb & 0x000000ff + ] + else if command is 6 + ch = content.shift() + fg = palidx++ + bg = palidx++ + for [ 0 .. 1 ] + rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) + colors.push [ + ( rgb >> 16 ) & 0x000000ff, + ( rgb >> 8 ) & 0x000000ff, + rgb & 0x000000ff + ] + + ch = String.fromCharCode( command ) unless ch? + + @screen[ y ][ x ] = { 'ch': ch, 'fg': fg, 'bg': bg } + x++ + if x == 80 + x = 0 + y++ + @screen[ y ] = [] + + @screen.pop() if @screen[ y ].length == 0 + @palette = new ImageTextModePalette( { colors: colors } ) + + +class @ImageTextModePCBoard extends @ImageTextMode + + constructor: ( options ) -> + super + @tabstop = 8 + @linewrap = 80 + @codes = { POFF: '', WAIT: '' } + this[k] = v for own k, v of options + + parse: ( content ) -> + @screen = [] + @state = 0 + @x = 0 + @y = 0 + @attr = 7 + + for key, val of @codes + code = new RegExp '@' + key + '@', 'g' + content.replace code, val + + content = content.split( '' ) + while ch = content.shift() + if @state is 0 + switch ch + when "\x1a" then @state = 2 + when '@' then @state = 1 + when "\n" + @x = 0 + @y++ + when "\r" then break + when "\t" + i = ( @x + 1 ) % @tabstop + @putpixel ' ' while i-- > 0 + else + @putpixel ch + else if @state is 1 + if ch is 'X' + @attr = ( parseInt( content.shift(), 16 ) << 4 ) + parseInt( content.shift(), 16 ) + else if ch + content[ 0..2 ].join( '' ) is 'CLS@' + content.shift() for [ 1 .. 3 ] + @screen = [] + else if ch + content[ 0..2 ].join( '' ) is 'POS:' + content.shift() for [ 1 .. 3 ] + @x = content.shift() + @x += content.shift() if content[ 0 ] isnt '@' + @x-- + + content.shift() + else + @putpixel '@' + @putpixel ch + + @state = 0 + else if @state is 2 + break + else + @state = 0 + + putpixel: ( ch ) -> + @screen[ @y ] = [] if !@screen[ @y ]? + @screen[ @y ][ @x ] = { ch: ch, attr: @attr } + + if ++@x >= @linewrap + @x = 0 + @y++ + + +class @ImageTextModeAVATAR extends @ImageTextMode + + constructor: ( options ) -> + super + @tabstop = 8 + @linewrap = 80 + this[k] = v for own k, v of options + + parse: ( content ) -> + @screen = [] + @x = 0 + @y = 0 + @attr = 3 + + content = content.split( '' ) + while ch = content.shift() + if ch is "\x1a" + break + else if ch is "\n" + @x = 0 + @y++ + else if ch is "\r" + continue + else if ch is "\t" + i = ( @x + 1 ) % @tabstop + @putpixel ' ' while i-- > 0 + else if ch.charCodeAt( 0 ) is 12 + @screen = [] + @attr = 3 + @insert = false + else if ch.charCodeAt( 0 ) is 25 + ch = content.shift() + i = content.shift().charCodeAt( 0 ) + @putpixel( ch ) while i-- > 0 + else if ch.charCodeAt( 0 ) is 22 + c = content.shift().charCodeAt( 0 ) + switch c + when 1 + @attr = content.shift().charCodeAt( 0 ) & 0x7f + when 2 + @attr |= 0x80 + when 3 + @y-- + @y = 0 if @y < 0 + when 4 + @y++ + when 5 + @x-- + @x = 0 if @x < 0 + when 6 + @x++ + when 7 + @screen[ @y ][ i ] = null for i in [ @x .. screen[ @y ].length - 1 ] + when 8 + @y = content.shift().charCodeAt( 0 ) - 1 + @x = content.shift().charCodeAt( 0 ) - 1 + @y = 0 if @y < 0 + @x = 0 if @x < 0 + else + @putpixel ch + + putpixel: ( ch ) -> + @screen[ @y ] = [] if !@screen[ @y ]? + @screen[ @y ][ @x ] = { ch: ch, attr: @attr } + + if ++@x >= @linewrap + @x = 0 + @y++ + + +class @ImageTextModeXBin extends @ImageTextMode + + # Header constants + PALETTE = 1 + FONT = 2 + COMPRESSED = 4 + NON_BLINK = 8 + FIVETWELVE_CHARS = 16 + + # Compression type constants + NO_COMPRESSION = 0 + CHARACTER_COMPRESSION = 64 + ATTRIBUTE_COMPRESSION = 128 + FULL_COMPRESSION = 192 + + # Compression byte constants + COMPRESSION_TYPE = 192 + COMPRESSION_COUNTER = 63 + + constructor: ( options ) -> + super + @header = { width: 0, height: 0, fontisze: 0, flags: 0 } + this[k] = v for own k, v of options + + parse: ( content ) -> + @screen = [] + headerData = content.substr( 0, 11 ) + if headerData.length isnt 11 || !headerData.match( '^XBIN\x1a' ) + throw new Error( 'File is not an XBin' ) + + @header.width = @unpackShort( headerData.substr( 5, 2 ) ) + @header.height = @unpackShort( headerData.substr( 7, 2 ) ) + @header.fontsize = @getByteAt( headerData.substr( 9, 1 ) ) + @header.flags = @getByteAt( headerData.substr( 10, 1 ) ) + offset = 11 + + if @header.flags & PALETTE + @parsePaletteData( content.substr( offset, 48 ) ); + offset += 48 + + if @header.flags & FONT + fontlength = @header.fontsize + if @header.flags & FIVETWELVE_CHARS + fontlength *= 512 + else + fontlength *= 256 + @parseFontData( content.substr( offset, fontlength ), @header.fontsize ); + offset += fontlength + + if @header.flags & COMPRESSED + @_parse_compressed( content.substr( offset ) ) + else + @_parse_uncompressed( content.substr( offset ) ) + + _parse_compressed: ( data ) -> + x = 0 + y = 0 + @screen[ y ] = [] + + data = data.split( '' ) + while info = data.shift() + info = @getByteAt( info, 0 ) + break if info == 26 + + type = info & COMPRESSION_TYPE + counter = ( info & COMPRESSION_COUNTER ) + 1 + + ch = null + attr = null + + while counter-- > 0 + switch type + when NO_COMPRESSION + ch = data.shift() + attr = data.shift() + when CHARACTER_COMPRESSION + ch = data.shift() if !ch? + attr = data.shift() + when ATTRIBUTE_COMPRESSION + attr = data.shift() if !attr? + ch = data.shift() + else + ch = data.shift() if !ch? + attr = data.shift() if !attr? + + @screen[ y ][ x ] = { ch: ch, attr: @getByteAt( attr, 0 ) } + + x++ + if x == @header.width + x = 0 + y++ + break if y == @header.height + @screen[ y ] = [] if !@screen[ y ]? + + _parse_uncompressed: ( data ) -> + x = 0 + y = 0 + @screen[ y ] = [] + + for i in [ 0 .. data.length - 2 ] by 2 + ch = data.substr( i, 1 ) + break if ch == "\x1a" + attr = @getByteAt( data, i + 1 ) + @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } + x++ + if x == @header.width + x = 0 + y++ + break if y == @header.height + @screen[ y ] = [] if !@screen[ y ]? + + getWidth: -> + return @header.width + + getHeight: -> + return @header.height + class @ImageTextModePalette constructor: ( options ) -> @@ -116,7 +866,6 @@ class @ImageTextModePaletteANSI extends @ImageTextModePalette [ 0x55, 0xff, 0xff ], [ 0xff, 0xff, 0xff ] ] - class @ImageTextModeFont constructor: ( options ) -> @chars = [] @@ -652,7 +1401,7 @@ class @ImageTextModeFont8x8 extends @ImageTextModeFont @[k] = v for own k, v of options class @ImageTextModeFontAmiga extends @ImageTextModeFont - constructor: ( options ) -> + constructor: ( options ) -> super @width @chars = [ [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], @@ -914,747 +1663,3 @@ class @ImageTextModeFontAmiga extends @ImageTextModeFont ] @height = 16 @[k] = v for own k, v of options - -class @ImageTextMode - - @VERSION = '0.01' - - constructor: ( options ) -> - @screen = [] - @palette = new ImageTextModePaletteVGA() - @font = new ImageTextModeFont8x16() - @[k] = v for own k, v of options - - parseUrl: ( url ) -> - req = new XMLHttpRequest() - req.open 'GET', url, false - req.overrideMimeType 'text/plain; charset=x-user-defined' - req.send null - content = if req.status is 200 or req.status is 0 then req.responseText else '' - @parse content - - unpackShort: ( data ) -> - shrt = ( @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 0 ) - if shrt < 0 - shrt += 65536 - shrt - - unpackLong: ( data ) -> - lng = ((( @getByteAt( data, 0 ) << 8 ) + @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 2 ) << 8 ) + @getByteAt( data, 3 ) - if lng < 0 - lng += 4294967296 - lng - - getByteAt: ( data, offset ) -> - data.charCodeAt( offset ) & 0xFF - -# could we replace this with math.max ? Not worth it,called once per view -# we COULD, but we'd do some crap like "Math.max.apply(null,blah) and that's not readable" - getWidth: -> - max = 0 - for y in [ 0 .. @screen.length - 1 ] - max = @screen[ y ].length if @screen[ y ]? && @screen[ y ].length > max - max - - getHeight: -> - @screen.length - - parsePaletteData: ( data ) -> - colors = [] - for i in [ 0 .. 45 ] by 3 - r = @getByteAt( data, i ) - r = r << 2 | r >> 4 - g = @getByteAt( data, i + 1 ) - g = g << 2 | g >> 4 - b = @getByteAt( data, i + 2 ) - b = b << 2 | b >> 4 - colors.push [ r, g, b ] - - @palette = new ImageTextModePalette( colors: colors ) - - parseFontData: ( data, height = 16 ) -> - chars = [] - for i in [ 0 ... data.length / height ] - chr = [] - for j in [ 0 ... height ] - chr.push @getByteAt( data, i * height + j ) - chars.push chr - @font = new ImageTextModeFont( { chars: chars, height: height } ) - -# the majority of time is spent in this routine -# list comprehension seems to speed up from 1.8 seconds to 1.29 seconds from first comprehension / cleanup? - - renderCanvas: ( canvasElem ) -> - w = @getWidth() * @font.width - h = @getHeight() * @font.height - - canvas = document.createElement 'canvas' - canvas.setAttribute 'width', w - canvas.setAttribute 'height', h - ctx = canvas.getContext '2d' - - for cy in [ 0 ... @screen.length ] - if @screen[ cy ]? - for cx in [ 0 ... @screen[ cy ].length ] - pixel = @screen[ cy ][ cx ] - curfillstyle = null - if pixel? - if pixel.attr? - fg = pixel.attr & 15 - bg = ( pixel.attr & 240 ) >> 4 - else - fg = pixel.fg - bg = pixel.bg - - px = cx * @font.width - py = cy * @font.height - - ctx.fillStyle = @palette.toRgbaString( @palette.colors[ bg ] ) - ctx.fillRect px, py, @font.width, @font.height - - ctx.fillStyle = @palette.toRgbaString( @palette.colors[ fg ] ) - chr = @font.chars[ pixel.ch.charCodeAt( 0 ) & 0xff ] - i = 0 - for line in chr - ctx.fillRect px + j, py + i, 1, 1 for j in [ 0 ... @font.width ] when line & (1 << @font.width - 1 - j ) - i += 1 - - canvasElem.setAttribute 'width', w - canvasElem.setAttribute 'height', h - ctx = canvasElem.getContext '2d' - ctx.drawImage canvas, 0, 0 - - toBinaryArray: (str) -> - buf = new ArrayBuffer(str.length * 2) # 2 bytes for each char - bufView = new Uint8Array(buf) - bufView[i] = str.charCodeAt(i) for i in [0...str.length] - buf - -# tests show the resulting code is not altered for results or for the logic -# but this makes the linter happy. (coffeescript's own I guess.) -# (the constructor right after the class def, before locals) - -class @ImageTextModeANSI extends @ImageTextMode - constructor: ( options ) -> - super @screen - super @font - @palette = new ImageTextModePaletteANSI - @tabstop = 8 - @linewrap = 80 - @[k] = v for own k, v of options - - ANSI_ESC = String.fromCharCode(0x1b) - ANSI_CSI = ANSI_ESC + '[' - ANSI_TEXT_PROP = 'm' - ANSI_RESET = '0' - ANSI_FG = '3' - ANSI_BG = '4' - ANSI_FG_INTENSE = '9' - ANSI_BG_INTENSE = '10' - ANSI_CUR_DOWN = 'B' - ANSI_SEP = ';' - ANSI_RETURN = 'A' - -# not going to mess with this for now, as I think it is the 'write' code -# for the actual ansi editor. That would be bad to mess up. -# did redo the for loops to read nicer tho. - - write: -> - content = "#{ ANSI_CSI }2J" # initiate document - for y in [0...@screen.length] - content += "\n" if !@screen[y]? - continue if !@screen[y]? - for x in [0...@getWidth()] - pixel = @screen[y][x] - if !pixel? - pixel = { ch: ' ', attr: 7 } - attr = @gen_args(pixel.attr) - if (attr != prevattr) - content += "#{ANSI_CSI}0;#{attr}#{ANSI_TEXT_PROP}" - prevattr = attr - content += if pixel.ch? then pixel.ch else ' ' - max_x = x - content += "#{ ANSI_CSI }0m" - @toBinaryArray(content) - - gen_args: ( attr ) -> - fg = 30 + ( attr & 7 ) - bg = 40 + ( ( attr & 112 ) >> 4) - bl = if attr & 128 then 5 else '' - intense = if attr & 8 then 1 else '' - -# um why do we make this attrs variable and not use it? - - attrs = a for a in [fg, bg, bl, intense] when a != '' - return [fg, bg, bl, intense].join(";") - - parse: ( content ) -> - @screen = [] - @state = 0 - @x = 0 - @y = 0 - @save_x = 0 - @save_y = 0 - @attr = 7 - @argbuf = '' - - content = content.split( '' ) - while ch = content.shift() - if @state is 0 - switch ch - when "\x1a" then @state = 3 - when "\x1b" then @state = 1 - when "\n" - @x = 0 - @y++ - when "\r" then break - when "\t" - i = ( @x + 1 ) % @tabstop - @putpixel ' ' while i-- > 0 - else - @putpixel ch - - else if @state is 1 - if ch isnt "[" - @putpixel "\x1b" - @putpixel "[" - @state = 0 - else - @state = 2 - - else if @state is 2 - if ch.match( '[A-Za-z]' ) - args = ( parseInt( i ) for i in @argbuf.split ';' ) - - switch ch - when "m" - for arg in args - if arg is 0 - @attr = 7 - else if arg is 1 - @attr |= 8 - else if arg is 5 - @attr |= 128 - else if 30 <= arg <= 37 - @attr &= 248 - @attr |= ( arg - 30 ) - else if 40 <= arg <= 47 - @attr &= 143 - @attr |= ( arg - 40 ) << 4 - - when "H", "f" - @y = ( args[ 0 ] or 1 ) - 1 - @x = ( args[ 1 ] or 1 ) - 1 - @y = 0 if @y < 0 - @x = 0 if @x < 0 - when "A" - @y -= args[ 0 ] or 1 - @y = 0 if @y < 0 - when "B" - @y += args[ 0 ] or 1 - when "C" - @x += args[ 0 ] or 1 - when "D" - @x -= args[ 0 ] or 1 - @x = 0 if @x < 0 - when "E" - @y += args[ 0 ] or 1 - @x = 0 - when "F" - @y -= args[ 0 ] or 1 - @y = 0 if @y > 0 - @x = 0 - when "G" - @x = ( args[ 0 ] or 1 ) - 1 - when "s" - @save_x = @x - @save_y = @y - when "u" - @x = @save_x - @y = @save_y - when "J" - if args.length is 0 or args[ 0 ] is 0 - @screen[ i ] = null for i in [ @y + 1 .. screen.length - 1 ] - @screen[ @y ][ i ] = null for i in [ @x .. screen[ @y ].length - 1 ] - else if args[ 0 ] is 1 - @screen[ i ] = null for i in [ 0 .. @y - 1 ] - @screen[ @y ][ i ] = null for i in [ 0 .. @x ] - else if args[ 0 ] is 2 - @x = 0 - @y = 0 - @screen = [] - when "K" - if args.length is 0 or args[ 0 ] is 0 - @screen[ @y ][ i ] = null for i in [ @x .. @screen[ @y ].length - 1 ] - else if args[ 0 ] is 1 - @screen[ @y ][ i ] = null for i in [ 0 .. @x ] - else if args[ 0 ] is 2 - @screen[ @y ] = null - - @argbuf = '' - @state = 0 - - else - @argbuf += ch - - else if @state is 3 - break - - else - @state = 0 - - - putpixel: ( ch ) -> - @screen[ @y ] = [] if !@screen[ @y ]? - @screen[ @y ][ @x ] = { ch: ch, attr: @attr } - - if ++@x >= @linewrap - @x = 0 - @y++ - -class @ImageTextModeBin extends @ImageTextMode - - constructor: ( options ) -> - super - @linewrap = 160 - this[k] = v for own k, v of options - - parse: ( content ) -> - x = 0 - y = 0 - @screen[ y ] = [] - - for i in [ 0 .. content.length - 2 ] by 2 - ch = content.substr( i, 1 ) - break if ch == "\x1a" - attr = @getByteAt( content, i + 1 ) - @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } - x++ - if x == @linewrap - x = 0 - y++ - @screen[ y ] = [] - - @screen.pop() if @screen[ y ].length == 0 - -class @ImageTextModeIDF extends @ImageTextMode - - constructor: ( options ) -> - super - @header = { x0: 0, x1: 0, y0: 0, y1: 0 } - this[k] = v for own k, v of options - - parse: ( content ) -> - headerData = content.substr( 0, 12 ) - if headerData.length isnt 12 || !headerData.match( '^\x041.4' ) - throw new Error( 'File is not an IDF' ) - - @header.x0 = @unpackShort( headerData.substr( 4, 2 ) ) - @header.y0 = @unpackShort( headerData.substr( 6, 2 ) ) - @header.x1 = @unpackShort( headerData.substr( 8, 2 ) ) - @header.y1 = @unpackShort( headerData.substr( 10, 2 ) ) - - eodata = content.length - 48 - 4096 - - if content.substr( content.length - 128, 5 ) == 'SAUCE' - eodata -= 128 - - @parseFontData( content.substr( eodata, 4096 ) ) - @parsePaletteData( content.substr( eodata + 4096, 48 ) ) - - y = 0 - x = 0 - @screen[ y ] = [] - offset = 12 - - while offset < eodata - buffer = content.substr( offset, 2 ) - info = @unpackShort( buffer ) - offset += 2 - len = 1 - - if info == 1 - len = @unpackShort( content.substr( offset, 2 ) ) & 255 - offset += 2 - buffer = content.substr( offset, 2 ) - offset += 2 - - ch = buffer.substr( 0, 1 ) - attr = @getByteAt( buffer, 1 ) - - for i in [ 1 .. len ] - @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } - x++ - if x > @header.x1 - x = 0 - y++ - @screen[ y ] = [] - - @screen.pop() if @screen[ y ].length == 0 - -class @ImageTextModeADF extends @ImageTextMode - - COLOR_INDEX = [ 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63 ] - - constructor: ( options ) -> - super - @header = { version: 0 } - this[k] = v for own k, v of options - - parse: ( content ) -> - @header.version = @getByteAt( content, 0 ) - @parsePaletteData( content.substr( 1, 192 ) ) - @parseFontData( content.substr( 193, 4096 ) ) - - x = 0 - y = 0 - @screen[ y ] = [] - - for i in [ 4289 .. content.length - 2 ] by 2 - ch = content.substr( i, 1 ) - break if ch == "\x1a" - attr = @getByteAt( content, i + 1 ) - @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } - x++ - if x == 80 - x = 0 - y++ - @screen[ y ] = [] - - @screen.pop() if @screen[ y ].length == 0 - - parsePaletteData: ( data ) -> - colors = [] - for i in COLOR_INDEX - j = i * 3 - r = @getByteAt( data, j ) - r = r << 2 | r >> 4 - g = @getByteAt( data, j + 1 ) - g = g << 2 | g >> 4 - b = @getByteAt( data, j + 2 ) - b = b << 2 | b >> 4 - colors.push [ r, g, b ] - - @palette = new ImageTextModePalette( { colors: colors } ) - -class @ImageTextModeTundra extends @ImageTextMode - - constructor: ( options ) -> - super - this[k] = v for own k, v of options - - parse: ( content ) -> - colors = [ [ 0, 0, 0 ] ] - palidx = 1 - x = 0 - y = 0 - fg = 0 - bg = 0 - - @screen[ y ] = [] - content = content.substr( 8 ).split( '' ) - while command = content.shift() - break if command == "\x1a" - command = command.charCodeAt( 0 ) - - if command is 1 - y = @unpackLong( content.splice( 0, 4 ).join( '' ) ) - x = @unpackLong( content.splice( 0, 4 ).join( '' ) ) - @screen[ y ] = [] if !@screen[ y ]? - continue - - ch = null - - if command is 2 - ch = content.shift() - rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) - fg = palidx++ - colors.push [ - ( rgb >> 16 ) & 0x000000ff, - ( rgb >> 8 ) & 0x000000ff, - rgb & 0x000000ff - ] - else if command is 4 - ch = content.shift() - rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) - bg = palidx++ - colors.push [ - ( rgb >> 16 ) & 0x000000ff, - ( rgb >> 8 ) & 0x000000ff, - rgb & 0x000000ff - ] - else if command is 6 - ch = content.shift() - fg = palidx++ - bg = palidx++ - for [ 0 .. 1 ] - rgb = @unpackLong( content.splice( 0, 4 ).join( '' ) ) - colors.push [ - ( rgb >> 16 ) & 0x000000ff, - ( rgb >> 8 ) & 0x000000ff, - rgb & 0x000000ff - ] - - ch = String.fromCharCode( command ) unless ch? - - @screen[ y ][ x ] = { 'ch': ch, 'fg': fg, 'bg': bg } - x++ - if x == 80 - x = 0 - y++ - @screen[ y ] = [] - - @screen.pop() if @screen[ y ].length == 0 - @palette = new ImageTextModePalette( { colors: colors } ) - -class @ImageTextModePCBoard extends @ImageTextMode - - constructor: ( options ) -> - super - @tabstop = 8 - @linewrap = 80 - @codes = { POFF: '', WAIT: '' } - this[k] = v for own k, v of options - - parse: ( content ) -> - @screen = [] - @state = 0 - @x = 0 - @y = 0 - @attr = 7 - - for key, val of @codes - code = new RegExp '@' + key + '@', 'g' - content.replace code, val - - content = content.split( '' ) - while ch = content.shift() - if @state is 0 - switch ch - when "\x1a" then @state = 2 - when '@' then @state = 1 - when "\n" - @x = 0 - @y++ - when "\r" then break - when "\t" - i = ( @x + 1 ) % @tabstop - @putpixel ' ' while i-- > 0 - else - @putpixel ch - else if @state is 1 - if ch is 'X' - @attr = ( parseInt( content.shift(), 16 ) << 4 ) + parseInt( content.shift(), 16 ) - else if ch + content[ 0..2 ].join( '' ) is 'CLS@' - content.shift() for [ 1 .. 3 ] - @screen = [] - else if ch + content[ 0..2 ].join( '' ) is 'POS:' - content.shift() for [ 1 .. 3 ] - @x = content.shift() - @x += content.shift() if content[ 0 ] isnt '@' - @x-- - - content.shift() - else - @putpixel '@' - @putpixel ch - - @state = 0 - else if @state is 2 - break - else - @state = 0 - - putpixel: ( ch ) -> - @screen[ @y ] = [] if !@screen[ @y ]? - @screen[ @y ][ @x ] = { ch: ch, attr: @attr } - - if ++@x >= @linewrap - @x = 0 - @y++ - -class @ImageTextModeAVATAR extends @ImageTextMode - - constructor: ( options ) -> - super - @tabstop = 8 - @linewrap = 80 - this[k] = v for own k, v of options - - parse: ( content ) -> - @screen = [] - @x = 0 - @y = 0 - @attr = 3 - - content = content.split( '' ) - while ch = content.shift() - if ch is "\x1a" - break - else if ch is "\n" - @x = 0 - @y++ - else if ch is "\r" - continue - else if ch is "\t" - i = ( @x + 1 ) % @tabstop - @putpixel ' ' while i-- > 0 - else if ch.charCodeAt( 0 ) is 12 - @screen = [] - @attr = 3 - @insert = false - else if ch.charCodeAt( 0 ) is 25 - ch = content.shift() - i = content.shift().charCodeAt( 0 ) - @putpixel( ch ) while i-- > 0 - else if ch.charCodeAt( 0 ) is 22 - c = content.shift().charCodeAt( 0 ) - switch c - when 1 - @attr = content.shift().charCodeAt( 0 ) & 0x7f - when 2 - @attr |= 0x80 - when 3 - @y-- - @y = 0 if @y < 0 - when 4 - @y++ - when 5 - @x-- - @x = 0 if @x < 0 - when 6 - @x++ - when 7 - @screen[ @y ][ i ] = null for i in [ @x .. screen[ @y ].length - 1 ] - when 8 - @y = content.shift().charCodeAt( 0 ) - 1 - @x = content.shift().charCodeAt( 0 ) - 1 - @y = 0 if @y < 0 - @x = 0 if @x < 0 - else - @putpixel ch - - putpixel: ( ch ) -> - @screen[ @y ] = [] if !@screen[ @y ]? - @screen[ @y ][ @x ] = { ch: ch, attr: @attr } - - if ++@x >= @linewrap - @x = 0 - @y++ - -class @ImageTextModeXBin extends @ImageTextMode - - # Header constants - PALETTE = 1 - FONT = 2 - COMPRESSED = 4 - NON_BLINK = 8 - FIVETWELVE_CHARS = 16 - - # Compression type constants - NO_COMPRESSION = 0 - CHARACTER_COMPRESSION = 64 - ATTRIBUTE_COMPRESSION = 128 - FULL_COMPRESSION = 192 - - # Compression byte constants - COMPRESSION_TYPE = 192 - COMPRESSION_COUNTER = 63 - - constructor: ( options ) -> - super - @header = { width: 0, height: 0, fontisze: 0, flags: 0 } - this[k] = v for own k, v of options - - parse: ( content ) -> - @screen = [] - headerData = content.substr( 0, 11 ) - if headerData.length isnt 11 || !headerData.match( '^XBIN\x1a' ) - throw new Error( 'File is not an XBin' ) - - @header.width = @unpackShort( headerData.substr( 5, 2 ) ) - @header.height = @unpackShort( headerData.substr( 7, 2 ) ) - @header.fontsize = @getByteAt( headerData.substr( 9, 1 ) ) - @header.flags = @getByteAt( headerData.substr( 10, 1 ) ) - offset = 11 - - if @header.flags & PALETTE - @parsePaletteData( content.substr( offset, 48 ) ); - offset += 48 - - if @header.flags & FONT - fontlength = @header.fontsize - if @header.flags & FIVETWELVE_CHARS - fontlength *= 512 - else - fontlength *= 256 - @parseFontData( content.substr( offset, fontlength ), @header.fontsize ); - offset += fontlength - - if @header.flags & COMPRESSED - @_parse_compressed( content.substr( offset ) ) - else - @_parse_uncompressed( content.substr( offset ) ) - - _parse_compressed: ( data ) -> - x = 0 - y = 0 - @screen[ y ] = [] - - data = data.split( '' ) - while info = data.shift() - info = @getByteAt( info, 0 ) - break if info == 26 - - type = info & COMPRESSION_TYPE - counter = ( info & COMPRESSION_COUNTER ) + 1 - - ch = null - attr = null - - while counter-- > 0 - switch type - when NO_COMPRESSION - ch = data.shift() - attr = data.shift() - when CHARACTER_COMPRESSION - ch = data.shift() if !ch? - attr = data.shift() - when ATTRIBUTE_COMPRESSION - attr = data.shift() if !attr? - ch = data.shift() - else - ch = data.shift() if !ch? - attr = data.shift() if !attr? - - @screen[ y ][ x ] = { ch: ch, attr: @getByteAt( attr, 0 ) } - - x++ - if x == @header.width - x = 0 - y++ - break if y == @header.height - @screen[ y ] = [] if !@screen[ y ]? - - _parse_uncompressed: ( data ) -> - x = 0 - y = 0 - @screen[ y ] = [] - - for i in [ 0 .. data.length - 2 ] by 2 - ch = data.substr( i, 1 ) - break if ch == "\x1a" - attr = @getByteAt( data, i + 1 ) - @screen[ y ][ x ] = { 'ch': ch, 'attr': attr } - x++ - if x == @header.width - x = 0 - y++ - break if y == @header.height - @screen[ y ] = [] if !@screen[ y ]? - - getWidth: -> - return @header.width - - getHeight: -> - return @header.height diff --git a/todo.txt b/todo.txt index 6545d00..49cfec6 100644 --- a/todo.txt +++ b/todo.txt @@ -5,6 +5,7 @@ (A) remove the SAUCE lines at bottom, return ANSI object for render @SAUCE (B) load SAUCE into 'info' lines (should be done at prep) @SAUCE x 2014-04-05 (A) Study 16colors site - how does IT remove sauce info? It DOESN'T. FUCK. +(A) Split coffeescript into files, use cake. (A) remove their lines like SAUCE, return ANSI object for render @OTHER (B) load other-info into 'info' (done at prep) @OTHER