diff --git a/xterm/xterm-tests.ts b/xterm/xterm-tests.ts
new file mode 100644
index 0000000000..0119ae135e
--- /dev/null
+++ b/xterm/xterm-tests.ts
@@ -0,0 +1,131 @@
+///
+
+import * as Terminal from 'xterm';
+
+declare var fetch: any;
+
+var term: Terminal,
+ protocol: any,
+ socketURL: string,
+ socket: WebSocket,
+ pid: number,
+ charWidth: number,
+ charHeight: number;
+
+var terminalContainer = document.getElementById('terminal-container'),
+ optionElements = {
+ cursorBlink: document.querySelector('#option-cursor-blink')
+ },
+ colsElement = document.getElementById('cols') as any,
+ rowsElement = document.getElementById('rows') as any;
+
+function setTerminalSize () {
+ var cols = parseInt(colsElement.value),
+ rows = parseInt(rowsElement.value),
+ width = (cols * charWidth).toString() + 'px',
+ height = (rows * charHeight).toString() + 'px';
+
+ terminalContainer.style.width = width;
+ terminalContainer.style.height = height;
+ term.resize(cols, rows);
+}
+
+colsElement.addEventListener('change', setTerminalSize);
+rowsElement.addEventListener('change', setTerminalSize);
+
+optionElements.cursorBlink.addEventListener('change', createTerminal);
+
+createTerminal();
+
+function createTerminal() {
+ // Clean terminal
+ while (terminalContainer.children.length) {
+ terminalContainer.removeChild(terminalContainer.children[0]);
+ }
+ term = new Terminal({
+ cursorBlink: (optionElements.cursorBlink as any).checked
+ });
+ term.on('resize', function (size: any) {
+ if (!pid) {
+ return;
+ }
+ var cols = size.cols,
+ rows = size.rows,
+ url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows;
+
+ fetch(url, {method: 'POST'});
+ });
+ protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
+ socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
+
+ term.open(terminalContainer);
+ // term.fit();
+
+ var cols = 20,
+ rows = 30;
+
+ colsElement.value = cols;
+ rowsElement.value = rows;
+
+ fetch('/terminals?cols=' + cols + '&rows=' + rows, {method: 'POST'}).then(function (res: any) {
+
+ charWidth = Math.ceil(term.element.offsetWidth / cols);
+ charHeight = Math.ceil(term.element.offsetHeight / rows);
+
+ res.text().then(function (pid: number) {
+ (window as any).pid = pid;
+ socketURL += pid;
+ socket = new WebSocket(socketURL);
+ socket.onopen = runRealTerminal;
+ socket.onclose = runFakeTerminal;
+ socket.onerror = runFakeTerminal;
+ });
+ });
+}
+
+
+function runRealTerminal() {
+ //term.attach(socket);
+ //term._initialized = true;
+}
+
+function runFakeTerminal() {
+ // if (term._initialized) {
+ // return;
+ // }
+
+ // term._initialized = true;
+
+ var shellprompt = '$ ';
+
+ // term.prompt = function () {
+ // term.write('\r\n' + shellprompt);
+ // };
+
+ term.writeln('Welcome to xterm.js');
+ term.writeln('This is a local terminal emulation, without a real terminal in the back-end.');
+ term.writeln('Type some keys and commands to play around.');
+ term.writeln('');
+ // term.prompt();
+
+ term.on('key', function (key, ev) {
+ var printable = (
+ !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey
+ );
+
+ if (ev.keyCode == 13) {
+ // term.prompt();
+ } else if (ev.keyCode == 8) {
+ // Do not delete the prompt
+ // if (term.x > 2) {
+ // term.write('\b \b');
+ // }
+ } else if (printable) {
+ term.write(key);
+ }
+ });
+
+ term.on('paste', function (data, ev) {
+ term.write(data);
+ });
+}
diff --git a/xterm/xterm.d.ts b/xterm/xterm.d.ts
new file mode 100644
index 0000000000..33558bd50d
--- /dev/null
+++ b/xterm/xterm.d.ts
@@ -0,0 +1,92 @@
+// Type definitions for xterm.js 2.0.1
+// Project: https://github.com/sourcelair/xterm.js/
+// Definitions by: Steven Silvester
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+/**
+ * Typing for an xterm terminal object.
+ */
+interface Xterm {
+
+ options: Xterm.IOptions;
+
+ element: HTMLElement;
+
+ textarea: HTMLElement;
+
+ attachCustomKeydownHandler(callback: (event: KeyboardEvent) => boolean): void;
+
+ blur(): void;
+
+ clear(): void;
+
+ destroy(): void;
+
+ focus(): void;
+
+ getOption(key: string): any;
+
+ on(event: string, callback: (...args: any[]) => void): void;
+
+ off(event: string, callback: (...args: any[]) => void): void;
+
+ open(parent: HTMLElement): void;
+
+ refresh(start: number, end: number, queue?: boolean): void;
+
+ reset(): void;
+
+ resize(x: number, y: number): void;
+
+ scrollDisp(n: number): void;
+
+ setOption(key: string, value: any): void;
+
+ write(text: string): void;
+
+ writeln(text: string): void;
+}
+
+
+interface XtermConstructor {
+ new (options?: Xterm.IOptions): Xterm;
+ (options?: Xterm.IOptions): Xterm;
+}
+
+
+/**
+ * A terminal options.
+ */
+declare module Xterm {
+ interface IOptions {
+ colors?: string[];
+
+ theme?: string;
+
+ convertEol?: boolean;
+
+ termName?: string;
+
+ geometry?: number[];
+
+ cursorBlink?: boolean;
+
+ visualBell?: boolean;
+
+ popOnBell?: boolean;
+
+ scrollback?: number;
+
+ debug?: boolean;
+
+ cancelEvents?: boolean;
+ }
+}
+
+
+declare var Xterm: XtermConstructor;
+
+
+declare module 'xterm' {
+ export = Xterm;
+}