$ -> timeout = (ms, f) -> setTimeout(f, ms) term = null palette = [ # normal colours '2e3436', 'cc0000', '4e9a06', 'c4a000', '3465a4', '75507b', '06989a', 'd3d7cf', # brighter versions (for bold, and 16-color sequences) '555753', 'ef2929', '8ae234', 'fce94f', '729fcf', 'ad7fa8', '34e2e2', 'eeeeec', # 256 colors '000000', '00005f', '000087', '0000af', '0000d7', '0000ff', '005f00', '005f5f', '005f87', '005faf', '005fd7', '005fff', '008700', '00875f', '008787', '0087af', '0087d7', '0087ff', '00af00', '00af5f', '00af87', '00afaf', '00afd7', '00afff', '00d700', '00d75f', '00d787', '00d7af', '00d7d7', '00d7ff', '00ff00', '00ff5f', '00ff87', '00ffaf', '00ffd7', '00ffff', '5f0000', '5f005f', '5f0087', '5f00af', '5f00d7', '5f00ff', '5f5f00', '5f5f5f', '5f5f87', '5f5faf', '5f5fd7', '5f5fff', '5f8700', '5f875f', '5f8787', '5f87af', '5f87d7', '5f87ff', '5faf00', '5faf5f', '5faf87', '5fafaf', '5fafd7', '5fafff', '5fd700', '5fd75f', '5fd787', '5fd7af', '5fd7d7', '5fd7ff', '5fff00', '5fff5f', '5fff87', '5fffaf', '5fffd7', '5fffff', '870000', '87005f', '870087', '8700af', '8700d7', '8700ff', '875f00', '875f5f', '875f87', '875faf', '875fd7', '875fff', '878700', '87875f', '878787', '8787af', '8787d7', '8787ff', '87af00', '87af5f', '87af87', '87afaf', '87afd7', '87afff', '87d700', '87d75f', '87d787', '87d7af', '87d7d7', '87d7ff', '87ff00', '87ff5f', '87ff87', '87ffaf', '87ffd7', '87ffff', 'af0000', 'af005f', 'af0087', 'af00af', 'af00d7', 'af00ff', 'af5f00', 'af5f5f', 'af5f87', 'af5faf', 'af5fd7', 'af5fff', 'af8700', 'af875f', 'af8787', 'af87af', 'af87d7', 'af87ff', 'afaf00', 'afaf5f', 'afaf87', 'afafaf', 'afafd7', 'afafff', 'afd700', 'afd75f', 'afd787', 'afd7af', 'afd7d7', 'afd7ff', 'afff00', 'afff5f', 'afff87', 'afffaf', 'afffd7', 'afffff', 'd70000', 'd7005f', 'd70087', 'd700af', 'd700d7', 'd700ff', 'd75f00', 'd75f5f', 'd75f87', 'd75faf', 'd75fd7', 'd75fff', 'd78700', 'd7875f', 'd78787', 'd787af', 'd787d7', 'd787ff', 'd7af00', 'd7af5f', 'd7af87', 'd7afaf', 'd7afd7', 'd7afff', 'd7d700', 'd7d75f', 'd7d787', 'd7d7af', 'd7d7d7', 'd7d7ff', 'd7ff00', 'd7ff5f', 'd7ff87', 'd7ffaf', 'd7ffd7', 'd7ffff', 'ff0000', 'ff005f', 'ff0087', 'ff00af', 'ff00d7', 'ff00ff', 'ff5f00', 'ff5f5f', 'ff5f87', 'ff5faf', 'ff5fd7', 'ff5fff', 'ff8700', 'ff875f', 'ff8787', 'ff87af', 'ff87d7', 'ff87ff', 'ffaf00', 'ffaf5f', 'ffaf87', 'ffafaf', 'ffafd7', 'ffafff', 'ffd700', 'ffd75f', 'ffd787', 'ffd7af', 'ffd7d7', 'ffd7ff', 'ffff00', 'ffff5f', 'ffff87', 'ffffaf', 'ffffd7', 'ffffff', '080808', '121212', '1c1c1c', '262626', '303030', '3a3a3a', '444444', '4e4e4e', '585858', '626262', '6c6c6c', '767676', '808080', '8a8a8a', '949494', '9e9e9e', 'a8a8a8', 'b2b2b2', 'bcbcbc', 'c6c6c6', 'd0d0d0', 'dadada', 'e4e4e4', 'eeeeee' ] $body = $('body') $body.css backgroundColor: "##{palette[0]}", color: "##{palette[7]}" socket = io.connect('http://localhost') color_to_css = (i) -> # handle inverse bit if i & 0x080000 index = ((i >> 8) & 0xff) else index = (i & 0xff) # lighten the basic 8 colors when they're bold if ((i & 0x10000) and index < 8) index += 8 return 'color: #' + palette[index] + '; ' bg_color_to_css = (i) -> # xor the inverse bit, to get color_to_css to use the bg color return 'background-' + color_to_css(i ^ 0x080000) stylize = (txt, style) -> if (txt.length == 0 or style == 0x000007) return txt css = '' css += 'font-weight: bold; ' if style & 0x010000 css += 'text-decoration: underline; ' if style & 0x020000 css += 'font-style: italic; ' if style & 0x200000 # italic css += 'opacity: 0; ' if style & 0x100000 # invisible css += color_to_css(style) if ((style & 0x0800ff) isnt 0x07) css += bg_color_to_css(style) if (style & 0x08ff00) return $('').text(txt) redraw_wait = false redraw_again = false redraw_now = -> $body.children().remove() for i in [0...term.text.length] div = $('
') txt = '' a = 0x000007 for j in [0...term.text[i].length] if (term.attributes[i][j] isnt a) if (txt.length) div.append(stylize(txt, a)) txt = '' a = term.attributes[i][j] txt += term.text[i][j] if txt.length div.append(stylize(txt, a)) $body.append(div) # limit to 50fps redraw = -> if (redraw_wait) redraw_again = true else redraw_now() redraw_wait = true redraw_again = false timeout 20, -> redraw_wait = false if (redraw_again) redraw_again = false redraw() update = (data) -> if (term) term.update(data) redraw() socket.on 'data', (data) -> update(data) socket.on 'init', (v) -> term = terminal.new(v.width, v.height) term.x = v.x term.y = v.y term.a = v.a term.text = v.text term.attributes = v.attributes redraw()