Created
April 1, 2010 07:39
-
-
Save grahamg/351513 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (a) { | |
a.browserTest = function (e, g) { | |
var f = "unknown", | |
d = "X", | |
b = function (k, j) { | |
for (var c = 0; c < j.length; c = c + 1) { | |
k = k.replace(j[c][0], j[c][1]) | |
} | |
return k | |
}, | |
h = function (l, k, j, n) { | |
var m = { | |
name: b((k.exec(l) || [f, f])[1], j) | |
}; | |
m[m.name] = true; | |
m.version = (n.exec(l) || [d, d, d, d])[3]; | |
if (m.name.match(/safari/) && m.version > 400) { | |
m.version = "2.0" | |
} | |
if (m.name === "presto") { | |
m.version = (a.browser.version > 9.27) ? "futhark" : "linear_b" | |
} | |
m.versionNumber = parseFloat(m.version, 10) || 0; | |
m.versionX = (m.version !== d) ? (m.version + "").substr(0, 1) : d; | |
m.className = m.name + m.versionX; | |
return m | |
}; | |
e = (e.match(/Opera|Navigator|Minefield|KHTML|Chrome/) ? b(e, [ | |
[/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ""], | |
["Chrome Safari", "Chrome"], | |
["KHTML", "Konqueror"], | |
["Minefield", "Firefox"], | |
["Navigator", "Netscape"] | |
]) : e).toLowerCase(); | |
a.browser = a.extend((!g) ? a.browser : {}, h(e, /(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari)/, [], /(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/)); | |
a.layout = h(e, /(gecko|konqueror|msie|opera|webkit)/, [ | |
["konqueror", "khtml"], | |
["msie", "trident"], | |
["opera", "presto"] | |
], /(applewebkit|rv|konqueror|msie)(\:|\/|\s)([a-z0-9\.]*?)(\;|\)|\s)/); | |
a.os = { | |
name: (/(win|mac|linux|sunos|solaris|iphone)/.exec(navigator.platform.toLowerCase()) || [f])[0].replace("sunos", "solaris") | |
}; | |
if (!g) { | |
a("html").addClass([a.os.name, a.browser.name, a.browser.className, a.layout.name, a.layout.className].join(" ")) | |
} | |
}; | |
a.browserTest(navigator.userAgent) | |
})(jQuery); | |
(function (b) { | |
b.hotkeys = { | |
version: "0.8", | |
specialKeys: { | |
8: "backspace", | |
9: "tab", | |
13: "return", | |
16: "shift", | |
17: "ctrl", | |
18: "alt", | |
19: "pause", | |
20: "capslock", | |
27: "esc", | |
32: "space", | |
33: "pageup", | |
34: "pagedown", | |
35: "end", | |
36: "home", | |
37: "left", | |
38: "up", | |
39: "right", | |
40: "down", | |
45: "insert", | |
46: "del", | |
96: "0", | |
97: "1", | |
98: "2", | |
99: "3", | |
100: "4", | |
101: "5", | |
102: "6", | |
103: "7", | |
104: "8", | |
105: "9", | |
106: "*", | |
107: "+", | |
109: "-", | |
110: ".", | |
111: "/", | |
112: "f1", | |
113: "f2", | |
114: "f3", | |
115: "f4", | |
116: "f5", | |
117: "f6", | |
118: "f7", | |
119: "f8", | |
120: "f9", | |
121: "f10", | |
122: "f11", | |
123: "f12", | |
144: "numlock", | |
145: "scroll", | |
191: "/", | |
224: "meta" | |
}, | |
shiftNums: { | |
"`": "~", | |
"1": "!", | |
"2": "@", | |
"3": "#", | |
"4": "$", | |
"5": "%", | |
"6": "^", | |
"7": "&", | |
"8": "*", | |
"9": "(", | |
"0": ")", | |
"-": "_", | |
"=": "+", | |
";": ": ", | |
"'": '"', | |
",": "<", | |
".": ">", | |
"/": "?", | |
"\\": "|" | |
} | |
}; | |
function a(d) { | |
if (typeof d.data !== "string") { | |
return | |
} | |
var c = d.handler, | |
e = d.data.toLowerCase().split(" "); | |
d.handler = function (n) { | |
if (this !== n.target && (/textarea|select/i.test(n.target.nodeName) || n.target.type === "text")) { | |
return | |
} | |
var h = n.type !== "keypress" && b.hotkeys.specialKeys[n.which], | |
o = String.fromCharCode(n.which).toLowerCase(), | |
k, m = "", | |
g = {}; | |
if (n.altKey && h !== "alt") { | |
m += "alt+" | |
} | |
if (n.ctrlKey && h !== "ctrl") { | |
m += "ctrl+" | |
} | |
if (n.metaKey && !n.ctrlKey && h !== "meta") { | |
m += "meta+" | |
} | |
if (n.shiftKey && h !== "shift") { | |
m += "shift+" | |
} | |
if (h) { | |
g[m + h] = true | |
} else { | |
g[m + o] = true; | |
g[m + b.hotkeys.shiftNums[o]] = true; | |
if (m === "shift+") { | |
g[b.hotkeys.shiftNums[o]] = true | |
} | |
} | |
for (var j = 0, f = e.length; j < f; j++) { | |
if (g[e[j]]) { | |
return c.apply(this, arguments) | |
} | |
} | |
} | |
} | |
b.each(["keydown", "keyup", "keypress"], function () { | |
b.event.special[this] = { | |
add: a | |
} | |
}) | |
})(jQuery); | |
function ltrim(b) { | |
if (b) { | |
var a = /\s*((\S+\s*)*)/; | |
return b.replace(a, "$1") | |
} | |
return "" | |
} | |
function rtrim(b) { | |
if (b) { | |
var a = /((\s*\S+)*)\s*/; | |
return b.replace(a, "$1") | |
} | |
return "" | |
} | |
function trim(a) { | |
if (a) { | |
return ltrim(rtrim(a)) | |
} | |
return "" | |
} | |
function entityEncode(a) { | |
a = a.replace(/&/g, "&"); | |
a = a.replace(/</g, "<"); | |
a = a.replace(/>/g, ">"); | |
a = a.replace(/ /g, " "); | |
if (/msie/i.test(navigator.userAgent)) { | |
a = a.replace("\n", " <br />") | |
} else { | |
a = a.replace(/\x0D/g, " <br />") | |
} | |
return a | |
} | |
var TerminalShell = { | |
commands: { | |
help: function help(a) { | |
a.print($("<h3>help</h3>")); | |
cmd_list = $("<ul>"); | |
$.each(this.commands, function (b, c) { | |
cmd_list.append($("<li>").text(b)) | |
}); | |
a.print(cmd_list) | |
}, | |
clear: function (a) { | |
a.clear() | |
} | |
}, | |
fallback: null, | |
process: function (a, b) { | |
var d = b.split(" "); | |
var c = d.shift(); | |
d.unshift(a); | |
if (c in this.commands) { | |
this.commands[c].apply(this, d) | |
} else { | |
if (!(this.fallback && this.fallback(a, b))) { | |
a.print('Unrecognized command. Type "help" for assistance.') | |
} | |
} | |
} | |
}; | |
var Terminal = { | |
buffer: "", | |
pos: 0, | |
history: [], | |
historyPos: 0, | |
promptActive: true, | |
cursorBlinkState: true, | |
_cursorBlinkTimeout: null, | |
spinnerIndex: 0, | |
_spinnerTimeout: null, | |
output: TerminalShell, | |
config: { | |
scrollStep: 20, | |
scrollSpeed: 100, | |
bg_color: "#000", | |
fg_color: "#FFF", | |
cursor_blink_time: 700, | |
cursor_style: "block", | |
prompt: "guest@xkcd:/$ ", | |
spinnerCharacters: ["[ ]", "[. ]", "[.. ]", "[...]"], | |
spinnerSpeed: 250, | |
typingSpeed: 50 | |
}, | |
sticky: { | |
keys: { | |
ctrl: false, | |
alt: false, | |
scroll: false | |
}, | |
set: function (a, b) { | |
this.keys[a] = b; | |
$("#" + a + "-indicator").toggle(this.keys[a]) | |
}, | |
toggle: function (a) { | |
this.set(a, !this.keys[a]) | |
}, | |
reset: function (a) { | |
this.set(a, false) | |
}, | |
resetAll: function (a) { | |
$.each(this.keys, $.proxy(function (b, c) { | |
this.reset(b) | |
}, this)) | |
} | |
}, | |
init: function () { | |
$(document).keypress($.proxy(function (c) { | |
if (!this.promptActive) { | |
return | |
} | |
if (c.which >= 32 && c.which <= 126) { | |
var b = String.fromCharCode(c.which); | |
var a = b.toLowerCase() | |
} else { | |
return | |
} | |
if ($.browser.opera && !(/[\w\s]/.test(b))) { | |
return | |
} | |
if (this.sticky.keys.ctrl) { | |
if (a == "w") { | |
this.deleteWord() | |
} else { | |
if (a == "h") { | |
Terminal.deleteCharacter(false) | |
} else { | |
if (a == "l") { | |
this.clear() | |
} else { | |
if (a == "a") { | |
this.setPos(0) | |
} else { | |
if (a == "e") { | |
this.setPos(this.buffer.length) | |
} | |
} | |
} | |
} | |
} | |
} else { | |
if (b) { | |
this.addCharacter(b); | |
c.preventDefault() | |
} | |
} | |
}, this)).bind("keydown", "return", function (a) { | |
if (Terminal.promptActive) { | |
Terminal.processInputBuffer() | |
} | |
}).bind("keydown", "backspace", function (a) { | |
a.preventDefault(); | |
Terminal.deleteCharacter(a.shiftKey) | |
}).bind("keydown", "del", function (a) { | |
Terminal.deleteCharacter(true) | |
}).bind("keydown", "left", function (a) { | |
Terminal.moveCursor(-1) | |
}).bind("keydown", "right", function (a) { | |
Terminal.moveCursor(1) | |
}).bind("keydown", "up", function (a) { | |
a.preventDefault(); | |
if (a.shiftKey || Terminal.sticky.keys.scroll) { | |
Terminal.scrollLine(-1) | |
} else { | |
if (a.ctrlKey || Terminal.sticky.keys.ctrl) { | |
Terminal.scrollPage(-1) | |
} else { | |
Terminal.moveHistory(-1) | |
} | |
} | |
}).bind("keydown", "down", function (a) { | |
a.preventDefault(); | |
if (a.shiftKey || Terminal.sticky.keys.scroll) { | |
Terminal.scrollLine(1) | |
} else { | |
if (a.ctrlKey || Terminal.sticky.keys.ctrl) { | |
Terminal.scrollPage(1) | |
} else { | |
Terminal.moveHistory(1) | |
} | |
} | |
}).bind("keydown", "pageup", function (a) { | |
Terminal.scrollPage(-1) | |
}).bind("keydown", "pagedown", function (a) { | |
Terminal.scrollPage(1) | |
}).bind("keydown", "home", function (a) { | |
a.preventDefault(); | |
if (a.ctrlKey || Terminal.sticky.keys.ctrl) { | |
Terminal.jumpToTop() | |
} else { | |
Terminal.setPos(0) | |
} | |
}).bind("keydown", "end", function (a) { | |
a.preventDefault(); | |
if (a.ctrlKey || Terminal.sticky.keys.ctrl) { | |
Terminal.jumpToBottom() | |
} else { | |
Terminal.setPos(Terminal.buffer.length) | |
} | |
}).bind("keydown", "tab", function (a) { | |
a.preventDefault() | |
}).keyup(function (b) { | |
var a = $.hotkeys.specialKeys[b.which]; | |
if (a in { | |
ctrl: true, | |
alt: true, | |
scroll: true | |
}) { | |
Terminal.sticky.toggle(a) | |
} else { | |
if (!(a in { | |
left: true, | |
right: true, | |
up: true, | |
down: true | |
})) { | |
Terminal.sticky.resetAll() | |
} | |
} | |
}); | |
$(window).resize(function (a) { | |
$("#screen").scrollTop($("#screen").attr("scrollHeight")) | |
}); | |
this.setCursorState(true); | |
this.setWorking(false); | |
$("#prompt").html(this.config.prompt); | |
$("#screen").hide().fadeIn("fast", function () { | |
$("#screen").triggerHandler("cli-load") | |
}) | |
}, | |
setCursorState: function (b, a) { | |
this.cursorBlinkState = b; | |
if (this.config.cursor_style == "block") { | |
if (b) { | |
$("#cursor").css({ | |
color: this.config.bg_color, | |
backgroundColor: this.config.fg_color | |
}) | |
} else { | |
$("#cursor").css({ | |
color: this.config.fg_color, | |
backgroundColor: this.config.bg_color | |
}) | |
} | |
} else { | |
if (b) { | |
$("#cursor").css("textDecoration", "underline") | |
} else { | |
$("#cursor").css("textDecoration", "none") | |
} | |
} | |
if (!a && this._cursorBlinkTimeout) { | |
window.clearTimeout(this._cursorBlinkTimeout); | |
this._cursorBlinkTimeout = null | |
} | |
this._cursorBlinkTimeout = window.setTimeout($.proxy(function () { | |
this.setCursorState(!this.cursorBlinkState, true) | |
}, this), this.config.cursor_blink_time) | |
}, | |
updateInputDisplay: function () { | |
var c = "", | |
b = " ", | |
a = ""; | |
if (this.pos < 0) { | |
this.pos = 0 | |
} | |
if (this.pos > this.buffer.length) { | |
this.pos = this.buffer.length | |
} | |
if (this.pos > 0) { | |
c = this.buffer.substr(0, this.pos) | |
} | |
if (this.pos < this.buffer.length) { | |
b = this.buffer.substr(this.pos, 1) | |
} | |
if (this.buffer.length - this.pos > 1) { | |
a = this.buffer.substr(this.pos + 1, this.buffer.length - this.pos - 1) | |
} | |
$("#lcommand").text(c); | |
$("#cursor").text(b); | |
if (b == " ") { | |
$("#cursor").html(" ") | |
} | |
$("#rcommand").text(a); | |
$("#prompt").text(this.config.prompt); | |
return | |
}, | |
clearInputBuffer: function () { | |
this.buffer = ""; | |
this.pos = 0; | |
this.updateInputDisplay() | |
}, | |
clear: function () { | |
$("#display").html("") | |
}, | |
addCharacter: function (b) { | |
var c = this.buffer.substr(0, this.pos); | |
var a = this.buffer.substr(this.pos, this.buffer.length - this.pos); | |
this.buffer = c + b + a; | |
this.pos++; | |
this.updateInputDisplay(); | |
this.setCursorState(true) | |
}, | |
deleteCharacter: function (a) { | |
var d = a ? 1 : 0; | |
if (this.pos >= (1 - d)) { | |
var c = this.buffer.substr(0, this.pos - 1 + d); | |
var b = this.buffer.substr(this.pos + d, this.buffer.length - this.pos - d); | |
this.buffer = c + b; | |
this.pos -= 1 - d; | |
this.updateInputDisplay() | |
} | |
this.setCursorState(true) | |
}, | |
deleteWord: function () { | |
if (this.pos > 0) { | |
var a = this.pos; | |
while (a > 0 && this.buffer.charAt(a) !== " ") { | |
a-- | |
} | |
left = this.buffer.substr(0, a - 1); | |
right = this.buffer.substr(a, this.buffer.length - this.pos); | |
this.buffer = left + right; | |
this.pos = a; | |
this.updateInputDisplay() | |
} | |
this.setCursorState(true) | |
}, | |
moveCursor: function (a) { | |
this.setPos(this.pos + a) | |
}, | |
setPos: function (a) { | |
if ((a >= 0) && (a <= this.buffer.length)) { | |
this.pos = a; | |
Terminal.updateInputDisplay() | |
} | |
this.setCursorState(true) | |
}, | |
moveHistory: function (b) { | |
var a = this.historyPos + b; | |
if ((a >= 0) && (a <= this.history.length)) { | |
if (a == this.history.length) { | |
this.clearInputBuffer() | |
} else { | |
this.buffer = this.history[a] | |
} | |
this.pos = this.buffer.length; | |
this.historyPos = a; | |
this.updateInputDisplay(); | |
this.jumpToBottom() | |
} | |
this.setCursorState(true) | |
}, | |
addHistory: function (a) { | |
this.historyPos = this.history.push(a) | |
}, | |
jumpToBottom: function () { | |
$("#screen").animate({ | |
scrollTop: $("#screen").attr("scrollHeight") | |
}, this.config.scrollSpeed, "linear") | |
}, | |
jumpToTop: function () { | |
$("#screen").animate({ | |
scrollTop: 0 | |
}, this.config.scrollSpeed, "linear") | |
}, | |
scrollPage: function (a) { | |
$("#screen").animate({ | |
scrollTop: $("#screen").scrollTop() + a * $("#screen").height() | |
}, this.config.scrollSpeed, "linear") | |
}, | |
scrollLine: function (a) { | |
$("#screen").scrollTop($("#screen").scrollTop() + a * this.config.scrollStep) | |
}, | |
print: function (a) { | |
if (!a) { | |
$("#display").append($("<div>")) | |
} else { | |
if (typeof a == "string") { | |
$("#display").append($("<p>").text(a)) | |
} else { | |
$("#display").append(a) | |
} | |
} | |
this.jumpToBottom() | |
}, | |
processInputBuffer: function (a) { | |
this.print($("<p>").addClass("command").text(this.config.prompt + this.buffer)); | |
var a = trim(this.buffer); | |
this.clearInputBuffer(); | |
if (a.length == 0) { | |
return false | |
} | |
this.addHistory(a); | |
if (this.output) { | |
return this.output.process(this, a) | |
} else { | |
return false | |
} | |
}, | |
setPromptActive: function (a) { | |
this.promptActive = a; | |
$("#inputline").toggle(this.promptActive) | |
}, | |
setWorking: function (a) { | |
if (a && !this._spinnerTimeout) { | |
$("#display .command:last-child").add("#bottomline").first().append($("#spinner")); | |
this._spinnerTimeout = window.setInterval($.proxy(function () { | |
if (!$("#spinner").is(":visible")) { | |
$("#spinner").fadeIn() | |
} | |
this.spinnerIndex = (this.spinnerIndex + 1) % this.config.spinnerCharacters.length; | |
$("#spinner").text(this.config.spinnerCharacters[this.spinnerIndex]) | |
}, this), this.config.spinnerSpeed); | |
this.setPromptActive(false); | |
$("#screen").triggerHandler("cli-busy") | |
} else { | |
if (!a && this._spinnerTimeout) { | |
clearInterval(this._spinnerTimeout); | |
this._spinnerTimeout = null; | |
$("#spinner").fadeOut(); | |
this.setPromptActive(true); | |
$("#screen").triggerHandler("cli-ready") | |
} | |
} | |
}, | |
runCommand: function (e) { | |
var b = 0; | |
var d = false; | |
this.promptActive = false; | |
var a = window.setInterval($.proxy(function c() { | |
if (b < e.length) { | |
this.addCharacter(e.charAt(b)); | |
b += 1 | |
} else { | |
clearInterval(a); | |
this.promptActive = true; | |
this.processInputBuffer() | |
} | |
}, this), this.config.typingSpeed) | |
} | |
}; | |
$(document).ready(function () { | |
$("#welcome").show(); | |
document.onkeydown = document.onkeypress = function (a) { | |
return $.hotkeys.specialKeys[a.keyCode] != "backspace" | |
}; | |
Terminal.init() | |
}); | |
function pathFilename(a) { | |
match = /\/([^\/]+)$/.exec(a); | |
if (match) { | |
return match[1] | |
} | |
} | |
function getRandomInt(b, a) { | |
return Math.floor(Math.random() * (a - b + 1)) + b | |
} | |
function randomChoice(a) { | |
return a[getRandomInt(0, a.length - 1)] | |
} | |
var xkcd = { | |
latest: null, | |
last: null, | |
cache: {}, | |
get: function (b, c, a) { | |
if (b == null) { | |
path = "http://xkcd.com/info.0.json" | |
} else { | |
if (Number(b)) { | |
path = "http://xkcd.com/" + b + "/info.0.json" | |
} else { | |
a(false); | |
return false | |
} | |
} | |
if (b in this.cache) { | |
this.last = this.cache[b]; | |
c(this.cache[b]) | |
} else { | |
return $.ajax({ | |
url: path, | |
dataType: "json", | |
success: $.proxy(function (d) { | |
this.last = this.cache[b] = d; | |
c(d) | |
}, this), | |
error: a | |
}) | |
} | |
} | |
}; | |
var xkcdDisplay = TerminalShell.commands.display = function (b, c) { | |
function a() { | |
b.print($("<p>").addClass("error").text('display: unable to open image "' + c + '": No such file or directory.')); | |
b.setWorking(false) | |
} | |
b.setWorking(true); | |
if (c) { | |
c = String(c); | |
num = Number(c.match(/^\d+/)); | |
filename = pathFilename(c) | |
} else { | |
num = xkcd.last.num | |
} | |
xkcd.get(num, function (d) { | |
if (!filename || (filename == pathFilename(d.img))) { | |
$("<img>").hide().load(function () { | |
b.print($("<h3>").text(d.num + ": " + d.title)); | |
$(this).fadeIn(); | |
var e = $(this); | |
if (d.link) { | |
e = $("<a>").attr("href", d.link).append($(this)) | |
} | |
b.print(e); | |
b.setWorking(false) | |
}).attr({ | |
src: d.img, | |
alt: d.title, | |
title: d.alt | |
}).addClass("comic") | |
} else { | |
a() | |
} | |
}, a) | |
}; | |
TerminalShell.commands.next = function (a) { | |
xkcdDisplay(a, xkcd.last.num + 1) | |
}; | |
TerminalShell.commands.previous = TerminalShell.commands.prev = function (a) { | |
xkcdDisplay(a, xkcd.last.num - 1) | |
}; | |
TerminalShell.commands.first = function (a) { | |
xkcdDisplay(a, 1) | |
}; | |
TerminalShell.commands.latest = TerminalShell.commands.last = function (a) { | |
xkcdDisplay(a, xkcd.latest.num) | |
}; | |
TerminalShell.commands.random = function (a) { | |
xkcdDisplay(a, getRandomInt(1, xkcd.latest.num)) | |
}; | |
TerminalShell.commands["goto"] = function (a, b) { | |
$("#screen").one("cli-ready", function (c) { | |
a.print('Did you mean "display"?') | |
}); | |
xkcdDisplay(a, 292) | |
}; | |
function linkFile(a) { | |
return { | |
type: "dir", | |
enter: function () { | |
window.location = a | |
} | |
} | |
} | |
Filesystem = { | |
"welcome.txt": { | |
type: "file", | |
read: function (a) { | |
a.print($("<h4>").text("Welcome to the unixkcd console.")); | |
a.print('To navigate, enter "next", "prev", "first", or "last".'); | |
a.print('Try "help" for more information.') | |
} | |
}, | |
"license.txt": { | |
type: "file", | |
read: function (a) { | |
a.print($("<p>").html('Client-side logic for Wordpress CLI theme :: <a href="http://thrind.xamai.ca/">R. McFarland, 2006, 2007, 2008</a>')); | |
a.print($("<p>").html('jQuery rewrite and overhaul :: <a href="http://www.chromakode.com/">Chromakode, 2010</a>')); | |
a.print(); | |
$.each(["This program is free software; you can redistribute it and/or", "modify it under the terms of the GNU General Public License", "as published by the Free Software Foundation; either version 2", "of the License, or (at your option) any later version.", "", "This program is distributed in the hope that it will be useful,", "but WITHOUT ANY WARRANTY; without even the implied warranty of", "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", "GNU General Public License for more details.", "", "You should have received a copy of the GNU General Public License", "along with this program; if not, write to the Free Software", "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."], function (c, b) { | |
a.print(b) | |
}) | |
} | |
} | |
}; | |
Filesystem.blog = Filesystem.blag = linkFile("http://blag.xkcd.com"); | |
Filesystem.forums = Filesystem.fora = linkFile("http://forums.xkcd.com/"); | |
Filesystem.store = linkFile("http://store.xkcd.com/"); | |
Filesystem.about = linkFile("http://xkcd.com/about/"); | |
TerminalShell.pwd = Filesystem; | |
TerminalShell.commands.cd = function (a, b) { | |
if (b in this.pwd) { | |
if (this.pwd[b].type == "dir") { | |
this.pwd[b].enter(a) | |
} else { | |
if (this.pwd[b].type == "file") { | |
a.print("cd: " + b + ": Not a directory") | |
} | |
} | |
} else { | |
a.print("cd: " + b + ": No such file or directory") | |
} | |
}; | |
TerminalShell.commands.ls = function (a, b) { | |
name_list = $("<ul>"); | |
$.each(this.pwd, function (c, d) { | |
if (d.type == "dir") { | |
c += "/" | |
} | |
name_list.append($("<li>").text(c)) | |
}); | |
a.print(name_list) | |
}; | |
TerminalShell.commands.cat = function (a, b) { | |
if (b in this.pwd) { | |
if (this.pwd[b].type == "file") { | |
this.pwd[b].read(a) | |
} else { | |
if (this.pwd[b].type == "dir") { | |
a.print("cat: " + b + ": Is a directory") | |
} | |
} | |
} else { | |
if (pathFilename(b) == "alt.txt") { | |
a.setWorking(true); | |
num = Number(b.match(/^\d+/)); | |
xkcd.get(num, function (c) { | |
a.print(c.alt); | |
a.setWorking(false) | |
}, function () { | |
a.print($("<p>").addClass("error").text('cat: "' + b + '": No such file or directory.')); | |
a.setWorking(false) | |
}) | |
} else { | |
a.print("You're a kitty!") | |
} | |
} | |
}; | |
TerminalShell.commands.reddit = function (c, b) { | |
b = Number(b); | |
if (b) { | |
a = "http://xkcd.com/" + b + "/" | |
} else { | |
var a = window.location | |
} | |
c.print($('<iframe src="http://www.reddit.com/static/button/button1.html?width=140&url=' + encodeURIComponent(a) + '&newwindow=1" height="22" width="140" scrolling="no" frameborder="0"></iframe>')) | |
}; | |
TerminalShell.commands["apt-get"] = function (c, d, a) { | |
if ((a != "sudo") && (d in { | |
update: true, | |
upgrade: true, | |
"dist-upgrade": true | |
})) { | |
c.print("E: Unable to lock the administration directory, are you root?") | |
} else { | |
if (d == "update") { | |
c.print("Reading package lists... Done") | |
} else { | |
if (d == "upgrade") { | |
if (($.browser.name == "msie") || ($.browser.name == "firefox" || $.browser.versionX < 3)) { | |
c.print($("<p>").append($("<a>").attr("href", "http://abetterbrowser.org/").text("To complete installation, click here."))) | |
} else { | |
c.print("This looks pretty good to me.") | |
} | |
} else { | |
if (d == "dist-upgrade") { | |
var e = { | |
win: "Windows", | |
mac: "OS X", | |
linux: "Linux" | |
}; | |
var b = $.os.name; | |
if (b in e) { | |
b = e[b] | |
} else { | |
b = "something fancy" | |
} | |
c.print("You are already running " + b + ".") | |
} else { | |
if (d == "moo") { | |
c.print(" (__)"); | |
c.print(" (oo)"); | |
c.print(" /------\\/ "); | |
c.print(" / | || "); | |
c.print("* /\\---/\\ "); | |
c.print(" ~~ ~~ "); | |
c.print('...."Have you mooed today?"...') | |
} else { | |
if (!d) { | |
c.print("This APT has Super Cow Powers.") | |
} else { | |
c.print("E: Invalid operation " + d) | |
} | |
} | |
} | |
} | |
} | |
} | |
}; | |
TerminalShell.commands.sudo = function (a) { | |
var c = Array.prototype.slice.call(arguments); | |
c.shift(); | |
if (c.join(" ") == "make me a sandwich") { | |
a.print("Okay.") | |
} else { | |
var b = c.shift(); | |
c.unshift(a); | |
c.push("sudo"); | |
if (b in TerminalShell.commands) { | |
this.commands[b].apply(this, c) | |
} else { | |
a.print("sudo: " + b + ": command not found") | |
} | |
} | |
}; | |
function oneLiner(a, c, b) { | |
if (c in b) { | |
a.print(b[c]); | |
return true | |
} else { | |
return false | |
} | |
} | |
TerminalShell.commands.man = function (a, b) { | |
pages = { | |
last: "Man, last night was AWESOME.", | |
help: "Man, help me out here.", | |
next: "Request confirmed; you will be reincarnated as a man next.", | |
cat: "You are now riding a half-man half-cat." | |
}; | |
if (!oneLiner(a, b, pages)) { | |
a.print("Oh, I'm sure you can figure it out.") | |
} | |
}; | |
Adventure = { | |
rooms: { | |
0: { | |
description: "You are at a computer using unixkcd.", | |
exits: { | |
west: 1, | |
south: 10 | |
} | |
}, | |
1: { | |
description: "Life is peaceful there.", | |
exits: { | |
east: 0, | |
west: 2 | |
} | |
}, | |
2: { | |
description: "In the open air.", | |
exits: { | |
east: 1, | |
west: 3 | |
} | |
}, | |
3: { | |
description: "Where the skies are blue.", | |
exits: { | |
east: 2, | |
west: 4 | |
} | |
}, | |
4: { | |
description: "This is what we're gonna do.", | |
exits: { | |
east: 3, | |
west: 5 | |
} | |
}, | |
5: { | |
description: "Sun in wintertime.", | |
exits: { | |
east: 4, | |
west: 6 | |
} | |
}, | |
6: { | |
description: "We will do just fine.", | |
exits: { | |
east: 5, | |
west: 7 | |
} | |
}, | |
7: { | |
description: "Where the skies are blue.", | |
exits: { | |
east: 6, | |
west: 8 | |
} | |
}, | |
8: { | |
description: "This is what we're gonna do.", | |
exits: { | |
east: 7 | |
} | |
}, | |
10: { | |
description: "A dark hallway.", | |
exits: { | |
north: 0, | |
south: 11 | |
}, | |
enter: function (a) { | |
if (!Adventure.status.lamp) { | |
a.print("You are eaten by a grue."); | |
Adventure.status.alive = false; | |
Adventure.goTo(a, 666) | |
} | |
} | |
}, | |
11: { | |
description: "Bed. This is where you sleep.", | |
exits: { | |
north: 10 | |
} | |
}, | |
666: { | |
description: "You're dead!" | |
} | |
}, | |
status: { | |
alive: true, | |
lamp: false | |
}, | |
goTo: function (a, b) { | |
Adventure.location = Adventure.rooms[b]; | |
Adventure.look(a); | |
if (Adventure.location.enter) { | |
Adventure.location.enter(a) | |
} | |
} | |
}; | |
Adventure.location = Adventure.rooms[0]; | |
TerminalShell.commands.look = Adventure.look = function (b) { | |
b.print(Adventure.location.description); | |
if (Adventure.location.exits) { | |
b.print(); | |
var a = []; | |
$.each(Adventure.location.exits, function (c, d) { | |
a.push(c) | |
}); | |
b.print("Exits: " + a.join(", ")) | |
} | |
}; | |
TerminalShell.commands.go = Adventure.go = function (a, b) { | |
if (Adventure.location.exits && b in Adventure.location.exits) { | |
Adventure.goTo(a, Adventure.location.exits[b]) | |
} else { | |
if (!b) { | |
a.print("Go where?") | |
} else { | |
a.print("You cannot go " + b + ".") | |
} | |
} | |
}; | |
TerminalShell.commands.light = function (a, b) { | |
if (b == "lamp") { | |
if (!Adventure.status.lamp) { | |
a.print("You set your lamp ablaze."); | |
Adventure.status.lamp = true | |
} else { | |
a.print("Your lamp is already lit!") | |
} | |
} else { | |
a.print("Light what?") | |
} | |
}; | |
TerminalShell.commands.help = function (a) { | |
a.print("You can do this.") | |
}; | |
TerminalShell.fallback = function (a, b) { | |
oneliners = { | |
"make me a sandwich": "What? Make it yourself.", | |
"i read the source code": "<3", | |
lpr: "PC LOAD LETTER", | |
"hello joshua": "How about a nice game of Global Thermonuclear War?", | |
xyzzy: "Nothing happens.", | |
date: "March 22nd" | |
}; | |
oneliners.emacs = "You should really use vim."; | |
oneliners.vi = oneliners.vim = "You should really use emacs."; | |
b = b.toLowerCase(); | |
if (!oneLiner(a, b, oneliners)) { | |
if (b == "asl" || b == "a/s/l") { | |
a.print(randomChoice(["2/AMD64/Server Rack", "328/M/Transylvania", "6/M/Battle School", "48/M/The White House", "7/F/Rapture", "Exactly your age/A gender you're attracted to/Far far away.", "7,831/F/Lothlórien", "42/M/FBI Field Office"])) | |
} else { | |
if (b == "find kitten") { | |
a.print($('<iframe width="800" height="600" src="http://www.robotfindskitten.net/rfk.swf"></iframe>')) | |
} else { | |
if (b == "buy stuff") { | |
Filesystem.store.enter() | |
} else { | |
return false | |
} | |
} | |
} | |
} | |
return true | |
}; | |
$(document).ready(function () { | |
Terminal.promptActive = false; | |
$("#screen").bind("cli-load", function (a) { | |
xkcd.get(null, function (b) { | |
xkcd.latest = b; | |
$("#screen").one("cli-ready", function (c) { | |
Terminal.runCommand("cat welcome.txt") | |
}); | |
Terminal.runCommand("display " + xkcd.latest.num + "/" + pathFilename(xkcd.latest.img)) | |
}) | |
}) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment