From 2e4147b4fa72c10a7f5864616b76516bfb5f384c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 1 Jan 2017 16:24:52 -0800 Subject: [PATCH 001/211] Use Tyriar/pty.js for Windows support Fixes #441 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 734bb6fb..6df2314a 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "jsdoc": "3.4.3", "mocha": "2.5.3", "nodemon": "1.10.2", - "pty.js": "0.3.1", + "pty.js": "https://github.com/Tyriar/pty.js/tarball/c75c2dcb6dcad83b0cb3ef2ae42d0448fb912642", "sleep": "^3.0.1", "sorcery": "^0.10.0", "tslint": "^4.0.2", From d2ef19dffe8f9c1b1e4d26d4aa41fed1029fae5f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 11:26:59 -0800 Subject: [PATCH 002/211] Remove var usage from Viewport Part of #335 --- src/Viewport.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Viewport.ts b/src/Viewport.ts index 3aa1319f..b8d8cd6d 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -46,13 +46,13 @@ export class Viewport { private refresh(charSize?: ClientRect): void { var size = charSize || this.charMeasureElement.getBoundingClientRect(); if (size.height > 0) { - var rowHeightChanged = size.height !== this.currentRowHeight; + const rowHeightChanged = size.height !== this.currentRowHeight; if (rowHeightChanged) { this.currentRowHeight = size.height; this.viewportElement.style.lineHeight = size.height + 'px'; this.terminal.rowContainer.style.lineHeight = size.height + 'px'; } - var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows; + const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows; if (rowHeightChanged || viewportHeightChanged) { this.lastRecordedViewportHeight = this.terminal.rows; this.viewportElement.style.height = size.height * this.terminal.rows + 'px'; @@ -74,14 +74,14 @@ export class Viewport { this.refresh(); } else { // If size has changed, refresh viewport - var size = this.charMeasureElement.getBoundingClientRect(); + const size = this.charMeasureElement.getBoundingClientRect(); if (size.height !== this.currentRowHeight) { this.refresh(size); } } // Sync scrollTop - var scrollTop = this.terminal.ydisp * this.currentRowHeight; + const scrollTop = this.terminal.ydisp * this.currentRowHeight; if (this.viewportElement.scrollTop !== scrollTop) { this.viewportElement.scrollTop = scrollTop; } @@ -93,8 +93,8 @@ export class Viewport { * @param ev The scroll event. */ private onScroll(ev: Event) { - var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); - var diff = newRow - this.terminal.ydisp; + const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); + const diff = newRow - this.terminal.ydisp; this.terminal.scrollDisp(diff, true); } @@ -110,7 +110,7 @@ export class Viewport { return; } // Fallback to WheelEvent.DOM_DELTA_PIXEL - var multiplier = 1; + let multiplier = 1; if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { multiplier = this.currentRowHeight; } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { From b9d374affa5333786b9665b94e6196e6d1ee5230 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 11:55:54 -0800 Subject: [PATCH 003/211] Add XON/XOFF and eparate write from processing Part of #425 --- demo/app.js | 3 +++ src/xterm.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/demo/app.js b/demo/app.js index a4122ace..b6bde384 100644 --- a/demo/app.js +++ b/demo/app.js @@ -60,6 +60,9 @@ app.ws('/terminals/:pid', function (ws, req) { term.on('data', function(data) { try { + // XOFF - stop pty pipe + // XON will be triggered by emulator before processing data chunk + term.write('\x13'); ws.send(data); } catch (ex) { // The WebSocket is not open, ignore diff --git a/src/xterm.js b/src/xterm.js index cd304186..a29412e6 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -196,6 +196,11 @@ function Terminal(options) { this.prefix = ''; this.postfix = ''; + // user input states + this.writeBuffer = []; + this.writeInProgress = false; + this.user_xoff = false; // user pressed XOFF + // leftover surrogate high from previous write invocation this.surrogate_high = ''; @@ -1341,8 +1346,27 @@ Terminal.prototype.scrollToBottom = function() { * @param {string} text The text to write to the terminal. */ Terminal.prototype.write = function(data) { + this.writeBuffer.push(data); + if (!this.writeInProgress) { + // Kick off a write which will write all data in sequence recursively + this.writeInProgress = true; + // Kick off an async innerWrite so more writes can come in while processing data + setTimeout(() => this.innerWrite(this.writeBuffer.shift())); + } +} + +Terminal.prototype.innerWrite = function(data) { var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; + // TODO: Need to have another buffer where data is held where write can grab lines from + // When this hits a certain threshold it should send this.write('\x13') + + // XON - about to process data, thus we can get more + // dont lift XOFF if user pressed it + if (!this.user_xoff) { + this.send('\x11'); + } + this.refreshStart = this.y; this.refreshEnd = this.y; @@ -2380,6 +2404,12 @@ Terminal.prototype.write = function(data) { this.updateRange(this.y); this.queueRefresh(this.refreshStart, this.refreshEnd); + + if (this.writeBuffer.length > 0) { + this.innerWrite(this.writeBuffer.shift()); + } else { + this.writeInProgress = false; + } }; /** @@ -2423,6 +2453,12 @@ Terminal.prototype.keyDown = function(ev) { var self = this; var result = this.evaluateKeyEscapeSequence(ev); + if (result.key === '\x13') { // XOFF + this.user_xoff = true; + } else if (result.key === '\x11') { // XON + this.user_xoff = false; + } + if (result.scrollDisp) { this.scrollDisp(result.scrollDisp); return this.cancel(ev, true); @@ -2728,6 +2764,7 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) { } break; } + return result; }; From 6b8c43ed7ffaf1f6e75e7523d84c5150e6f127c8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 12:58:36 -0800 Subject: [PATCH 004/211] Send \x13 when a write buffer threadhold is reached --- demo/app.js | 3 --- src/xterm.js | 28 +++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/demo/app.js b/demo/app.js index b6bde384..a4122ace 100644 --- a/demo/app.js +++ b/demo/app.js @@ -60,9 +60,6 @@ app.ws('/terminals/:pid', function (ws, req) { term.on('data', function(data) { try { - // XOFF - stop pty pipe - // XON will be triggered by emulator before processing data chunk - term.write('\x13'); ws.send(data); } catch (ex) { // The WebSocket is not open, ignore diff --git a/src/xterm.js b/src/xterm.js index a29412e6..58392ba1 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1347,24 +1347,38 @@ Terminal.prototype.scrollToBottom = function() { */ Terminal.prototype.write = function(data) { this.writeBuffer.push(data); - if (!this.writeInProgress) { + + // Pause pty process if the write buffer becomes too large so xterm.js can catch up + if (this.writeBuffer.length > 1000 && !this.user_xoff) { + // XOFF - stop pty pipe + // XON will be triggered by emulator before processing data chunk + this.send('\x13'); + } + + if (!this.writeInProgress && this.writeBuffer.length > 0) { // Kick off a write which will write all data in sequence recursively this.writeInProgress = true; // Kick off an async innerWrite so more writes can come in while processing data - setTimeout(() => this.innerWrite(this.writeBuffer.shift())); + var self = this; + setTimeout(function () { + self.innerWrite(self.writeBuffer.shift()); + }); } } Terminal.prototype.innerWrite = function(data) { var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; - +console.log('writeBuffer length: ' + this.writeBuffer.length); // TODO: Need to have another buffer where data is held where write can grab lines from // When this hits a certain threshold it should send this.write('\x13') // XON - about to process data, thus we can get more // dont lift XOFF if user pressed it if (!this.user_xoff) { - this.send('\x11'); + // Resume pty process to get more data + if (this.writeBuffer.length < 200) { + this.send('\x11'); + } } this.refreshStart = this.y; @@ -2406,7 +2420,11 @@ Terminal.prototype.innerWrite = function(data) { this.queueRefresh(this.refreshStart, this.refreshEnd); if (this.writeBuffer.length > 0) { - this.innerWrite(this.writeBuffer.shift()); + var self = this; + // Start a new async innerWrite to prevent a stack overflow + setTimeout(function () { + self.innerWrite(self.writeBuffer.shift()); + }); } else { this.writeInProgress = false; } From e66b1c57049253c5e4d7abbf17ef55b67bf4e2e2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 15:26:41 -0800 Subject: [PATCH 005/211] Add write buffer pause and refresh frame skip --- src/xterm.js | 104 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 58392ba1..5bfa50a6 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -37,6 +37,19 @@ var document = (typeof window != 'undefined') ? window.document : null; */ var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6; +/** + * The amount of write requests to queue before sending an XOFF signal to the + * pty process. This number must be small in order for ^C and similar sequences + * to be responsive. + */ +var WRITE_BUFFER_PAUSE_THRESHOLD = 0; + +/** + * The maximum number of refresh frames to skip when the write buffer is non- + * empty. + */ +var MAX_REFRESH_FRAME_SKIP = 6; + /** * Terminal */ @@ -199,7 +212,18 @@ function Terminal(options) { // user input states this.writeBuffer = []; this.writeInProgress = false; - this.user_xoff = false; // user pressed XOFF + this.refreshFramesSkipped = 0; + + /** + * Whether _xterm.js_ sent XOFF in order to catch up with the pty process. + * This is a distinct state from writeStopped so that if the user requested + * XOFF via ^S that it will not automatically resume when the writeBuffer goes + * below threshold. + */ + this.xoffSentToCatchUp = false; + + /** Whether writing has been stopped as a result of XOFF */ + this.writeStopped = false; // leftover surrogate high from previous write invocation this.surrogate_high = ''; @@ -1014,27 +1038,36 @@ Terminal.prototype.queueRefresh = function(start, end) { Terminal.prototype.refreshLoop = function() { // Don't refresh if there were no row changes if (this.refreshRowsQueue.length > 0) { - var start; - var end; - if (this.refreshRowsQueue.length > 4) { - // Just do a full refresh when 5+ refreshes are queued - start = 0; - end = this.rows - 1; - } else { - // Get start and end rows that need refreshing - start = this.refreshRowsQueue[0].start; - end = this.refreshRowsQueue[0].end; - for (var i = 1; i < this.refreshRowsQueue.length; i++) { - if (this.refreshRowsQueue[i].start < start) { - start = this.refreshRowsQueue[i].start; - } - if (this.refreshRowsQueue[i].end > end) { - end = this.refreshRowsQueue[i].end; + // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it + // will need to be immediately refreshed anyway. This saves a lot of + // rendering time as the viewport DOM does not need to be refreshed, no + // scroll events, no layouts, etc. + var skipFrame = this.writeBuffer.length > 0 && this.refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + + if (!skipFrame) { + this.refreshFramesSkipped = 0; + var start; + var end; + if (this.refreshRowsQueue.length > 4) { + // Just do a full refresh when 5+ refreshes are queued + start = 0; + end = this.rows - 1; + } else { + // Get start and end rows that need refreshing + start = this.refreshRowsQueue[0].start; + end = this.refreshRowsQueue[0].end; + for (var i = 1; i < this.refreshRowsQueue.length; i++) { + if (this.refreshRowsQueue[i].start < start) { + start = this.refreshRowsQueue[i].start; + } + if (this.refreshRowsQueue[i].end > end) { + end = this.refreshRowsQueue[i].end; + } } } + this.refreshRowsQueue = []; + this.refresh(start, end); } - this.refreshRowsQueue = []; - this.refresh(start, end); } window.requestAnimationFrame(this.refreshLoop.bind(this)); } @@ -1348,11 +1381,14 @@ Terminal.prototype.scrollToBottom = function() { Terminal.prototype.write = function(data) { this.writeBuffer.push(data); - // Pause pty process if the write buffer becomes too large so xterm.js can catch up - if (this.writeBuffer.length > 1000 && !this.user_xoff) { + // Send XOFF to pause the pty process if the write buffer becomes too large so + // xterm.js can catch up before more data is sent. This is necessary in order + // to keep signals such as ^C responsive. + if (!this.xoffSentToCatchUp && this.writeBuffer.length > WRITE_BUFFER_PAUSE_THRESHOLD) { // XOFF - stop pty pipe // XON will be triggered by emulator before processing data chunk this.send('\x13'); + this.xoffSentToCatchUp = true; } if (!this.writeInProgress && this.writeBuffer.length > 0) { @@ -1368,17 +1404,12 @@ Terminal.prototype.write = function(data) { Terminal.prototype.innerWrite = function(data) { var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; -console.log('writeBuffer length: ' + this.writeBuffer.length); - // TODO: Need to have another buffer where data is held where write can grab lines from - // When this hits a certain threshold it should send this.write('\x13') - // XON - about to process data, thus we can get more - // dont lift XOFF if user pressed it - if (!this.user_xoff) { - // Resume pty process to get more data - if (this.writeBuffer.length < 200) { - this.send('\x11'); - } + // If XOFF was sent in order to catch up with the pty process, resume it if + // the writeBuffer is empty to allow more data to come in. + if (this.xoffSentToCatchUp && this.writeBuffer.length === 0) { + this.send('\x11'); + this.xoffSentToCatchUp = false; } this.refreshStart = this.y; @@ -2421,10 +2452,13 @@ console.log('writeBuffer length: ' + this.writeBuffer.length); if (this.writeBuffer.length > 0) { var self = this; + +// TODO: async makes this too slow, need to change to iterative to prevent potential stack overflow + // Start a new async innerWrite to prevent a stack overflow - setTimeout(function () { + //setTimeout(function () { self.innerWrite(self.writeBuffer.shift()); - }); + //}); } else { this.writeInProgress = false; } @@ -2472,9 +2506,9 @@ Terminal.prototype.keyDown = function(ev) { var result = this.evaluateKeyEscapeSequence(ev); if (result.key === '\x13') { // XOFF - this.user_xoff = true; + this.writeStopped = true; } else if (result.key === '\x11') { // XON - this.user_xoff = false; + this.writeStopped = false; } if (result.scrollDisp) { From dc5efa886a11d61388d06b46f0bd6f9d5e28c31d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 15:29:23 -0800 Subject: [PATCH 006/211] Make innerWrite iterative --- src/xterm.js | 1935 +++++++++++++++++++++++++------------------------- 1 file changed, 963 insertions(+), 972 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 5bfa50a6..0849775d 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1397,1071 +1397,1062 @@ Terminal.prototype.write = function(data) { // Kick off an async innerWrite so more writes can come in while processing data var self = this; setTimeout(function () { - self.innerWrite(self.writeBuffer.shift()); + self.innerWrite(); }); } } -Terminal.prototype.innerWrite = function(data) { - var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; +Terminal.prototype.innerWrite = function() { + while (this.writeBuffer.length > 0) { + var data = this.writeBuffer.shift(); + var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; - // If XOFF was sent in order to catch up with the pty process, resume it if - // the writeBuffer is empty to allow more data to come in. - if (this.xoffSentToCatchUp && this.writeBuffer.length === 0) { - this.send('\x11'); - this.xoffSentToCatchUp = false; - } - - this.refreshStart = this.y; - this.refreshEnd = this.y; - - // apply leftover surrogate high from last write - if (this.surrogate_high) { - data = this.surrogate_high + data; - this.surrogate_high = ''; - } - - for (; i < l; i++) { - ch = data[i]; - - // FIXME: higher chars than 0xa0 are not allowed in escape sequences - // --> maybe move to default - code = data.charCodeAt(i); - if (0xD800 <= code && code <= 0xDBFF) { - // we got a surrogate high - // get surrogate low (next 2 bytes) - low = data.charCodeAt(i+1); - if (isNaN(low)) { - // end of data stream, save surrogate high - this.surrogate_high = ch; - continue; - } - code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; - ch += data.charAt(i+1); + // If XOFF was sent in order to catch up with the pty process, resume it if + // the writeBuffer is empty to allow more data to come in. + if (this.xoffSentToCatchUp && this.writeBuffer.length === 0) { + this.send('\x11'); + this.xoffSentToCatchUp = false; } - // surrogate low - already handled above - if (0xDC00 <= code && code <= 0xDFFF) - continue; - switch (this.state) { - case normal: - switch (ch) { - case '\x07': - this.bell(); - break; - // '\n', '\v', '\f' - case '\n': - case '\x0b': - case '\x0c': - if (this.convertEol) { + this.refreshStart = this.y; + this.refreshEnd = this.y; + + // apply leftover surrogate high from last write + if (this.surrogate_high) { + data = this.surrogate_high + data; + this.surrogate_high = ''; + } + + for (; i < l; i++) { + ch = data[i]; + + // FIXME: higher chars than 0xa0 are not allowed in escape sequences + // --> maybe move to default + code = data.charCodeAt(i); + if (0xD800 <= code && code <= 0xDBFF) { + // we got a surrogate high + // get surrogate low (next 2 bytes) + low = data.charCodeAt(i+1); + if (isNaN(low)) { + // end of data stream, save surrogate high + this.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(i+1); + } + // surrogate low - already handled above + if (0xDC00 <= code && code <= 0xDFFF) + continue; + switch (this.state) { + case normal: + switch (ch) { + case '\x07': + this.bell(); + break; + + // '\n', '\v', '\f' + case '\n': + case '\x0b': + case '\x0c': + if (this.convertEol) { + this.x = 0; + } + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } + break; + + // '\r' + case '\r': this.x = 0; - } - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); - } - break; + break; - // '\r' - case '\r': - this.x = 0; - break; - - // '\b' - case '\x08': - if (this.x > 0) { - this.x--; - } - break; - - // '\t' - case '\t': - this.x = this.nextStop(); - break; - - // shift out - case '\x0e': - this.setgLevel(1); - break; - - // shift in - case '\x0f': - this.setgLevel(0); - break; - - // '\e' - case '\x1b': - this.state = escaped; - break; - - default: - // ' ' - // calculate print space - // expensive call, therefore we save width in line buffer - ch_width = wcwidth(code); - - if (ch >= ' ') { - if (this.charset && this.charset[ch]) { - ch = this.charset[ch]; + // '\b' + case '\x08': + if (this.x > 0) { + this.x--; } + break; - row = this.y + this.ybase; + // '\t' + case '\t': + this.x = this.nextStop(); + break; - // insert combining char in last cell - // FIXME: needs handling after cursor jumps - if (!ch_width && this.x) { - // dont overflow left - if (this.lines.get(row)[this.x-1]) { - if (!this.lines.get(row)[this.x-1][2]) { + // shift out + case '\x0e': + this.setgLevel(1); + break; - // found empty cell after fullwidth, need to go 2 cells back - if (this.lines.get(row)[this.x-2]) - this.lines.get(row)[this.x-2][1] += ch; + // shift in + case '\x0f': + this.setgLevel(0); + break; + // '\e' + case '\x1b': + this.state = escaped; + break; + + default: + // ' ' + // calculate print space + // expensive call, therefore we save width in line buffer + ch_width = wcwidth(code); + + if (ch >= ' ') { + if (this.charset && this.charset[ch]) { + ch = this.charset[ch]; + } + + row = this.y + this.ybase; + + // insert combining char in last cell + // FIXME: needs handling after cursor jumps + if (!ch_width && this.x) { + // dont overflow left + if (this.lines.get(row)[this.x-1]) { + if (!this.lines.get(row)[this.x-1][2]) { + + // found empty cell after fullwidth, need to go 2 cells back + if (this.lines.get(row)[this.x-2]) + this.lines.get(row)[this.x-2][1] += ch; + + } else { + this.lines.get(row)[this.x-1][1] += ch; + } + this.updateRange(this.y); + } + break; + } + + // goto next line if ch would overflow + // TODO: needs a global min terminal width of 2 + if (this.x+ch_width-1 >= this.cols) { + // autowrap - DECAWM + if (this.wraparoundMode) { + this.x = 0; + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } } else { - this.lines.get(row)[this.x-1][1] += ch; + this.x = this.cols-1; + if(ch_width===2) // FIXME: check for xterm behavior + continue; } - this.updateRange(this.y); } - break; - } + row = this.y + this.ybase; - // goto next line if ch would overflow - // TODO: needs a global min terminal width of 2 - if (this.x+ch_width-1 >= this.cols) { - // autowrap - DECAWM - if (this.wraparoundMode) { - this.x = 0; - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); + // insert mode: move characters to right + if (this.insertMode) { + // do this twice for a fullwidth char + for (var moves=0; moves Normal Keypad (DECKPNM). + case '>': + this.log('Switching back to normal keypad.'); + this.applicationKeypad = false; + this.viewport.syncScrollArea(); + this.state = normal; + break; + + default: + this.state = normal; + this.error('Unknown ESC control: %s.', ch); + break; + } + break; + + case charset: + switch (ch) { + case '0': // DEC Special Character and Line Drawing Set. + cs = Terminal.charsets.SCLD; + break; + case 'A': // UK + cs = Terminal.charsets.UK; + break; + case 'B': // United States (USASCII). + cs = Terminal.charsets.US; + break; + case '4': // Dutch + cs = Terminal.charsets.Dutch; + break; + case 'C': // Finnish + case '5': + cs = Terminal.charsets.Finnish; + break; + case 'R': // French + cs = Terminal.charsets.French; + break; + case 'Q': // FrenchCanadian + cs = Terminal.charsets.FrenchCanadian; + break; + case 'K': // German + cs = Terminal.charsets.German; + break; + case 'Y': // Italian + cs = Terminal.charsets.Italian; + break; + case 'E': // NorwegianDanish + case '6': + cs = Terminal.charsets.NorwegianDanish; + break; + case 'Z': // Spanish + cs = Terminal.charsets.Spanish; + break; + case 'H': // Swedish + case '7': + cs = Terminal.charsets.Swedish; + break; + case '=': // Swiss + cs = Terminal.charsets.Swiss; + break; + case '/': // ISOLatin (actually /A) + cs = Terminal.charsets.ISOLatin; + i++; + break; + default: // Default + cs = Terminal.charsets.US; + break; + } + this.setgCharset(this.gcharset, cs); + this.gcharset = null; + this.state = normal; + break; + + case osc: + // OSC Ps ; Pt ST + // OSC Ps ; Pt BEL + // Set Text Parameters. + if (ch === '\x1b' || ch === '\x07') { + if (ch === '\x1b') i++; + + this.params.push(this.currentParam); + + switch (this.params[0]) { + case 0: + case 1: + case 2: + if (this.params[1]) { + this.title = this.params[1]; + this.handleTitle(this.title); + } break; - case ')': - this.gcharset = 1; + case 3: + // set X property break; - case '*': - this.gcharset = 2; + case 4: + case 5: + // change dynamic colors break; - case '+': - this.gcharset = 3; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + // change dynamic ui colors break; - case '-': - this.gcharset = 1; + case 46: + // change log file break; - case '.': - this.gcharset = 2; + case 50: + // dynamic font + break; + case 51: + // emacs shell + break; + case 52: + // manipulate selection data + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + // reset colors break; } - this.state = charset; - break; - // Designate G3 Character Set (VT300). - // A = ISO Latin-1 Supplemental. - // Not implemented. - case '/': - this.gcharset = 3; - this.state = charset; - i--; - break; - - // ESC N - // Single Shift Select of G2 Character Set - // ( SS2 is 0x8e). This affects next character only. - case 'N': - break; - // ESC O - // Single Shift Select of G3 Character Set - // ( SS3 is 0x8f). This affects next character only. - case 'O': - break; - // ESC n - // Invoke the G2 Character Set as GL (LS2). - case 'n': - this.setgLevel(2); - break; - // ESC o - // Invoke the G3 Character Set as GL (LS3). - case 'o': - this.setgLevel(3); - break; - // ESC | - // Invoke the G3 Character Set as GR (LS3R). - case '|': - this.setgLevel(3); - break; - // ESC } - // Invoke the G2 Character Set as GR (LS2R). - case '}': - this.setgLevel(2); - break; - // ESC ~ - // Invoke the G1 Character Set as GR (LS1R). - case '~': - this.setgLevel(1); - break; - - // ESC 7 Save Cursor (DECSC). - case '7': - this.saveCursor(); + this.params = []; + this.currentParam = 0; this.state = normal; - break; + } else { + if (!this.params.length) { + if (ch >= '0' && ch <= '9') { + this.currentParam = + this.currentParam * 10 + ch.charCodeAt(0) - 48; + } else if (ch === ';') { + this.params.push(this.currentParam); + this.currentParam = ''; + } + } else { + this.currentParam += ch; + } + } + break; - // ESC 8 Restore Cursor (DECRC). - case '8': - this.restoreCursor(); - this.state = normal; + case csi: + // '?', '>', '!' + if (ch === '?' || ch === '>' || ch === '!') { + this.prefix = ch; break; + } - // ESC # 3 DEC line height/width - case '#': - this.state = normal; - i++; + // 0 - 9 + if (ch >= '0' && ch <= '9') { + this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; break; + } - // ESC H Tab Set (HTS is 0x88). - case 'H': - this.tabSet(); + // '$', '"', ' ', '\'' + if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { + this.postfix = ch; break; - - // ESC = Application Keypad (DECKPAM). - case '=': - this.log('Serial port requested application keypad.'); - this.applicationKeypad = true; - this.viewport.syncScrollArea(); - this.state = normal; - break; - - // ESC > Normal Keypad (DECKPNM). - case '>': - this.log('Switching back to normal keypad.'); - this.applicationKeypad = false; - this.viewport.syncScrollArea(); - this.state = normal; - break; - - default: - this.state = normal; - this.error('Unknown ESC control: %s.', ch); - break; - } - break; - - case charset: - switch (ch) { - case '0': // DEC Special Character and Line Drawing Set. - cs = Terminal.charsets.SCLD; - break; - case 'A': // UK - cs = Terminal.charsets.UK; - break; - case 'B': // United States (USASCII). - cs = Terminal.charsets.US; - break; - case '4': // Dutch - cs = Terminal.charsets.Dutch; - break; - case 'C': // Finnish - case '5': - cs = Terminal.charsets.Finnish; - break; - case 'R': // French - cs = Terminal.charsets.French; - break; - case 'Q': // FrenchCanadian - cs = Terminal.charsets.FrenchCanadian; - break; - case 'K': // German - cs = Terminal.charsets.German; - break; - case 'Y': // Italian - cs = Terminal.charsets.Italian; - break; - case 'E': // NorwegianDanish - case '6': - cs = Terminal.charsets.NorwegianDanish; - break; - case 'Z': // Spanish - cs = Terminal.charsets.Spanish; - break; - case 'H': // Swedish - case '7': - cs = Terminal.charsets.Swedish; - break; - case '=': // Swiss - cs = Terminal.charsets.Swiss; - break; - case '/': // ISOLatin (actually /A) - cs = Terminal.charsets.ISOLatin; - i++; - break; - default: // Default - cs = Terminal.charsets.US; - break; - } - this.setgCharset(this.gcharset, cs); - this.gcharset = null; - this.state = normal; - break; - - case osc: - // OSC Ps ; Pt ST - // OSC Ps ; Pt BEL - // Set Text Parameters. - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') i++; + } this.params.push(this.currentParam); - - switch (this.params[0]) { - case 0: - case 1: - case 2: - if (this.params[1]) { - this.title = this.params[1]; - this.handleTitle(this.title); - } - break; - case 3: - // set X property - break; - case 4: - case 5: - // change dynamic colors - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - // change dynamic ui colors - break; - case 46: - // change log file - break; - case 50: - // dynamic font - break; - case 51: - // emacs shell - break; - case 52: - // manipulate selection data - break; - case 104: - case 105: - case 110: - case 111: - case 112: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: - // reset colors - break; - } - - this.params = []; this.currentParam = 0; + + // ';' + if (ch === ';') break; + this.state = normal; - } else { - if (!this.params.length) { - if (ch >= '0' && ch <= '9') { - this.currentParam = - this.currentParam * 10 + ch.charCodeAt(0) - 48; - } else if (ch === ';') { - this.params.push(this.currentParam); - this.currentParam = ''; - } - } else { - this.currentParam += ch; - } - } - break; - case csi: - // '?', '>', '!' - if (ch === '?' || ch === '>' || ch === '!') { - this.prefix = ch; - break; - } + switch (ch) { + // CSI Ps A + // Cursor Up Ps Times (default = 1) (CUU). + case 'A': + this.cursorUp(this.params); + break; - // 0 - 9 - if (ch >= '0' && ch <= '9') { - this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; - break; - } + // CSI Ps B + // Cursor Down Ps Times (default = 1) (CUD). + case 'B': + this.cursorDown(this.params); + break; - // '$', '"', ' ', '\'' - if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { - this.postfix = ch; - break; - } + // CSI Ps C + // Cursor Forward Ps Times (default = 1) (CUF). + case 'C': + this.cursorForward(this.params); + break; - this.params.push(this.currentParam); - this.currentParam = 0; + // CSI Ps D + // Cursor Backward Ps Times (default = 1) (CUB). + case 'D': + this.cursorBackward(this.params); + break; - // ';' - if (ch === ';') break; + // CSI Ps ; Ps H + // Cursor Position [row;column] (default = [1,1]) (CUP). + case 'H': + this.cursorPos(this.params); + break; - this.state = normal; + // CSI Ps J Erase in Display (ED). + case 'J': + this.eraseInDisplay(this.params); + break; - switch (ch) { - // CSI Ps A - // Cursor Up Ps Times (default = 1) (CUU). - case 'A': - this.cursorUp(this.params); - break; - - // CSI Ps B - // Cursor Down Ps Times (default = 1) (CUD). - case 'B': - this.cursorDown(this.params); - break; - - // CSI Ps C - // Cursor Forward Ps Times (default = 1) (CUF). - case 'C': - this.cursorForward(this.params); - break; - - // CSI Ps D - // Cursor Backward Ps Times (default = 1) (CUB). - case 'D': - this.cursorBackward(this.params); - break; - - // CSI Ps ; Ps H - // Cursor Position [row;column] (default = [1,1]) (CUP). - case 'H': - this.cursorPos(this.params); - break; - - // CSI Ps J Erase in Display (ED). - case 'J': - this.eraseInDisplay(this.params); - break; - - // CSI Ps K Erase in Line (EL). - case 'K': - this.eraseInLine(this.params); - break; - - // CSI Pm m Character Attributes (SGR). - case 'm': - if (!this.prefix) { - this.charAttributes(this.params); - } - break; - - // CSI Ps n Device Status Report (DSR). - case 'n': - if (!this.prefix) { - this.deviceStatus(this.params); - } - break; - - /** - * Additions - */ - - // CSI Ps @ - // Insert Ps (Blank) Character(s) (default = 1) (ICH). - case '@': - this.insertChars(this.params); - break; - - // CSI Ps E - // Cursor Next Line Ps Times (default = 1) (CNL). - case 'E': - this.cursorNextLine(this.params); - break; - - // CSI Ps F - // Cursor Preceding Line Ps Times (default = 1) (CNL). - case 'F': - this.cursorPrecedingLine(this.params); - break; - - // CSI Ps G - // Cursor Character Absolute [column] (default = [row,1]) (CHA). - case 'G': - this.cursorCharAbsolute(this.params); - break; - - // CSI Ps L - // Insert Ps Line(s) (default = 1) (IL). - case 'L': - this.insertLines(this.params); - break; - - // CSI Ps M - // Delete Ps Line(s) (default = 1) (DL). - case 'M': - this.deleteLines(this.params); - break; - - // CSI Ps P - // Delete Ps Character(s) (default = 1) (DCH). - case 'P': - this.deleteChars(this.params); - break; - - // CSI Ps X - // Erase Ps Character(s) (default = 1) (ECH). - case 'X': - this.eraseChars(this.params); - break; - - // CSI Pm ` Character Position Absolute - // [column] (default = [row,1]) (HPA). - case '`': - this.charPosAbsolute(this.params); - break; - - // 141 61 a * HPR - - // Horizontal Position Relative - case 'a': - this.HPositionRelative(this.params); - break; - - // CSI P s c - // Send Device Attributes (Primary DA). - // CSI > P s c - // Send Device Attributes (Secondary DA) - case 'c': - this.sendDeviceAttributes(this.params); - break; - - // CSI Pm d - // Line Position Absolute [row] (default = [1,column]) (VPA). - case 'd': - this.linePosAbsolute(this.params); - break; - - // 145 65 e * VPR - Vertical Position Relative - case 'e': - this.VPositionRelative(this.params); - break; - - // CSI Ps ; Ps f - // Horizontal and Vertical Position [row;column] (default = - // [1,1]) (HVP). - case 'f': - this.HVPosition(this.params); - break; - - // CSI Pm h Set Mode (SM). - // CSI ? Pm h - mouse escape codes, cursor escape codes - case 'h': - this.setMode(this.params); - break; - - // CSI Pm l Reset Mode (RM). - // CSI ? Pm l - case 'l': - this.resetMode(this.params); - break; - - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - case 'r': - this.setScrollRegion(this.params); - break; - - // CSI s - // Save cursor (ANSI.SYS). - case 's': - this.saveCursor(this.params); - break; - - // CSI u - // Restore cursor (ANSI.SYS). - case 'u': - this.restoreCursor(this.params); - break; - - /** - * Lesser Used - */ - - // CSI Ps I - // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). - case 'I': - this.cursorForwardTab(this.params); - break; - - // CSI Ps S Scroll up Ps lines (default = 1) (SU). - case 'S': - this.scrollUp(this.params); - break; - - // CSI Ps T Scroll down Ps lines (default = 1) (SD). - // CSI Ps ; Ps ; Ps ; Ps ; Ps T - // CSI > Ps; Ps T - case 'T': - // if (this.prefix === '>') { - // this.resetTitleModes(this.params); - // break; - // } - // if (this.params.length > 2) { - // this.initMouseTracking(this.params); - // break; - // } - if (this.params.length < 2 && !this.prefix) { - this.scrollDown(this.params); - } - break; - - // CSI Ps Z - // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). - case 'Z': - this.cursorBackwardTab(this.params); - break; - - // CSI Ps b Repeat the preceding graphic character Ps times (REP). - case 'b': - this.repeatPrecedingCharacter(this.params); - break; - - // CSI Ps g Tab Clear (TBC). - case 'g': - this.tabClear(this.params); - break; - - // CSI Pm i Media Copy (MC). - // CSI ? Pm i - // case 'i': - // this.mediaCopy(this.params); - // break; + // CSI Ps K Erase in Line (EL). + case 'K': + this.eraseInLine(this.params); + break; // CSI Pm m Character Attributes (SGR). - // CSI > Ps; Ps m - // case 'm': // duplicate - // if (this.prefix === '>') { - // this.setResources(this.params); - // } else { - // this.charAttributes(this.params); - // } - // break; + case 'm': + if (!this.prefix) { + this.charAttributes(this.params); + } + break; // CSI Ps n Device Status Report (DSR). - // CSI > Ps n - // case 'n': // duplicate - // if (this.prefix === '>') { - // this.disableModifiers(this.params); - // } else { - // this.deviceStatus(this.params); - // } - // break; + case 'n': + if (!this.prefix) { + this.deviceStatus(this.params); + } + break; - // CSI > Ps p Set pointer mode. - // CSI ! p Soft terminal reset (DECSTR). - // CSI Ps$ p - // Request ANSI mode (DECRQM). - // CSI ? Ps$ p - // Request DEC private mode (DECRQM). - // CSI Ps ; Ps " p - case 'p': - switch (this.prefix) { - // case '>': - // this.setPointerMode(this.params); - // break; - case '!': - this.softReset(this.params); - break; - // case '?': - // if (this.postfix === '$') { - // this.requestPrivateMode(this.params); - // } - // break; - // default: - // if (this.postfix === '"') { - // this.setConformanceLevel(this.params); - // } else if (this.postfix === '$') { - // this.requestAnsiMode(this.params); - // } - // break; - } - break; + /** + * Additions + */ - // CSI Ps q Load LEDs (DECLL). - // CSI Ps SP q - // CSI Ps " q - // case 'q': - // if (this.postfix === ' ') { - // this.setCursorStyle(this.params); - // break; - // } - // if (this.postfix === '"') { - // this.setCharProtectionAttr(this.params); - // break; - // } - // this.loadLEDs(this.params); - // break; + // CSI Ps @ + // Insert Ps (Blank) Character(s) (default = 1) (ICH). + case '@': + this.insertChars(this.params); + break; + + // CSI Ps E + // Cursor Next Line Ps Times (default = 1) (CNL). + case 'E': + this.cursorNextLine(this.params); + break; + + // CSI Ps F + // Cursor Preceding Line Ps Times (default = 1) (CNL). + case 'F': + this.cursorPrecedingLine(this.params); + break; + + // CSI Ps G + // Cursor Character Absolute [column] (default = [row,1]) (CHA). + case 'G': + this.cursorCharAbsolute(this.params); + break; + + // CSI Ps L + // Insert Ps Line(s) (default = 1) (IL). + case 'L': + this.insertLines(this.params); + break; + + // CSI Ps M + // Delete Ps Line(s) (default = 1) (DL). + case 'M': + this.deleteLines(this.params); + break; + + // CSI Ps P + // Delete Ps Character(s) (default = 1) (DCH). + case 'P': + this.deleteChars(this.params); + break; + + // CSI Ps X + // Erase Ps Character(s) (default = 1) (ECH). + case 'X': + this.eraseChars(this.params); + break; + + // CSI Pm ` Character Position Absolute + // [column] (default = [row,1]) (HPA). + case '`': + this.charPosAbsolute(this.params); + break; + + // 141 61 a * HPR - + // Horizontal Position Relative + case 'a': + this.HPositionRelative(this.params); + break; + + // CSI P s c + // Send Device Attributes (Primary DA). + // CSI > P s c + // Send Device Attributes (Secondary DA) + case 'c': + this.sendDeviceAttributes(this.params); + break; + + // CSI Pm d + // Line Position Absolute [row] (default = [1,column]) (VPA). + case 'd': + this.linePosAbsolute(this.params); + break; + + // 145 65 e * VPR - Vertical Position Relative + case 'e': + this.VPositionRelative(this.params); + break; + + // CSI Ps ; Ps f + // Horizontal and Vertical Position [row;column] (default = + // [1,1]) (HVP). + case 'f': + this.HVPosition(this.params); + break; + + // CSI Pm h Set Mode (SM). + // CSI ? Pm h - mouse escape codes, cursor escape codes + case 'h': + this.setMode(this.params); + break; + + // CSI Pm l Reset Mode (RM). + // CSI ? Pm l + case 'l': + this.resetMode(this.params); + break; // CSI Ps ; Ps r // Set Scrolling Region [top;bottom] (default = full size of win- // dow) (DECSTBM). // CSI ? Pm r - // CSI Pt; Pl; Pb; Pr; Ps$ r - // case 'r': // duplicate - // if (this.prefix === '?') { - // this.restorePrivateValues(this.params); - // } else if (this.postfix === '$') { - // this.setAttrInRectangle(this.params); - // } else { - // this.setScrollRegion(this.params); - // } - // break; - - // CSI s Save cursor (ANSI.SYS). - // CSI ? Pm s - // case 's': // duplicate - // if (this.prefix === '?') { - // this.savePrivateValues(this.params); - // } else { - // this.saveCursor(this.params); - // } - // break; - - // CSI Ps ; Ps ; Ps t - // CSI Pt; Pl; Pb; Pr; Ps$ t - // CSI > Ps; Ps t - // CSI Ps SP t - // case 't': - // if (this.postfix === '$') { - // this.reverseAttrInRectangle(this.params); - // } else if (this.postfix === ' ') { - // this.setWarningBellVolume(this.params); - // } else { - // if (this.prefix === '>') { - // this.setTitleModeFeature(this.params); - // } else { - // this.manipulateWindow(this.params); - // } - // } - // break; - - // CSI u Restore cursor (ANSI.SYS). - // CSI Ps SP u - // case 'u': // duplicate - // if (this.postfix === ' ') { - // this.setMarginBellVolume(this.params); - // } else { - // this.restoreCursor(this.params); - // } - // break; - - // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v - // case 'v': - // if (this.postfix === '$') { - // this.copyRectagle(this.params); - // } - // break; - - // CSI Pt ; Pl ; Pb ; Pr ' w - // case 'w': - // if (this.postfix === '\'') { - // this.enableFilterRectangle(this.params); - // } - // break; - - // CSI Ps x Request Terminal Parameters (DECREQTPARM). - // CSI Ps x Select Attribute Change Extent (DECSACE). - // CSI Pc; Pt; Pl; Pb; Pr$ x - // case 'x': - // if (this.postfix === '$') { - // this.fillRectangle(this.params); - // } else { - // this.requestParameters(this.params); - // //this.__(this.params); - // } - // break; - - // CSI Ps ; Pu ' z - // CSI Pt; Pl; Pb; Pr$ z - // case 'z': - // if (this.postfix === '\'') { - // this.enableLocatorReporting(this.params); - // } else if (this.postfix === '$') { - // this.eraseRectangle(this.params); - // } - // break; - - // CSI Pm ' { - // CSI Pt; Pl; Pb; Pr$ { - // case '{': - // if (this.postfix === '\'') { - // this.setLocatorEvents(this.params); - // } else if (this.postfix === '$') { - // this.selectiveEraseRectangle(this.params); - // } - // break; - - // CSI Ps ' | - // case '|': - // if (this.postfix === '\'') { - // this.requestLocatorPosition(this.params); - // } - // break; - - // CSI P m SP } - // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. - // case '}': - // if (this.postfix === ' ') { - // this.insertColumns(this.params); - // } - // break; - - // CSI P m SP ~ - // Delete P s Column(s) (default = 1) (DECDC), VT420 and up - // case '~': - // if (this.postfix === ' ') { - // this.deleteColumns(this.params); - // } - // break; - - default: - this.error('Unknown CSI code: %s.', ch); - break; - } - - this.prefix = ''; - this.postfix = ''; - break; - - case dcs: - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') i++; - - switch (this.prefix) { - // User-Defined Keys (DECUDK). - case '': + case 'r': + this.setScrollRegion(this.params); break; - // Request Status String (DECRQSS). - // test: echo -e '\eP$q"p\e\\' - case '$q': - var pt = this.currentParam - , valid = false; + // CSI s + // Save cursor (ANSI.SYS). + case 's': + this.saveCursor(this.params); + break; - switch (pt) { - // DECSCA - case '"q': - pt = '0"q'; - break; + // CSI u + // Restore cursor (ANSI.SYS). + case 'u': + this.restoreCursor(this.params); + break; - // DECSCL - case '"p': - pt = '61"p'; - break; + /** + * Lesser Used + */ - // DECSTBM - case 'r': - pt = '' - + (this.scrollTop + 1) - + ';' - + (this.scrollBottom + 1) - + 'r'; - break; + // CSI Ps I + // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). + case 'I': + this.cursorForwardTab(this.params); + break; - // SGR - case 'm': - pt = '0m'; - break; + // CSI Ps S Scroll up Ps lines (default = 1) (SU). + case 'S': + this.scrollUp(this.params); + break; - default: - this.error('Unknown DCS Pt: %s.', pt); - pt = ''; - break; + // CSI Ps T Scroll down Ps lines (default = 1) (SD). + // CSI Ps ; Ps ; Ps ; Ps ; Ps T + // CSI > Ps; Ps T + case 'T': + // if (this.prefix === '>') { + // this.resetTitleModes(this.params); + // break; + // } + // if (this.params.length > 2) { + // this.initMouseTracking(this.params); + // break; + // } + if (this.params.length < 2 && !this.prefix) { + this.scrollDown(this.params); } - - this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\'); break; - // Set Termcap/Terminfo Data (xterm, experimental). - case '+p': + // CSI Ps Z + // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). + case 'Z': + this.cursorBackwardTab(this.params); break; - // Request Termcap/Terminfo String (xterm, experimental) - // Regular xterm does not even respond to this sequence. - // This can cause a small glitch in vim. - // test: echo -ne '\eP+q6b64\e\\' - case '+q': - var pt = this.currentParam - , valid = false; - - this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\'); + // CSI Ps b Repeat the preceding graphic character Ps times (REP). + case 'b': + this.repeatPrecedingCharacter(this.params); break; + // CSI Ps g Tab Clear (TBC). + case 'g': + this.tabClear(this.params); + break; + + // CSI Pm i Media Copy (MC). + // CSI ? Pm i + // case 'i': + // this.mediaCopy(this.params); + // break; + + // CSI Pm m Character Attributes (SGR). + // CSI > Ps; Ps m + // case 'm': // duplicate + // if (this.prefix === '>') { + // this.setResources(this.params); + // } else { + // this.charAttributes(this.params); + // } + // break; + + // CSI Ps n Device Status Report (DSR). + // CSI > Ps n + // case 'n': // duplicate + // if (this.prefix === '>') { + // this.disableModifiers(this.params); + // } else { + // this.deviceStatus(this.params); + // } + // break; + + // CSI > Ps p Set pointer mode. + // CSI ! p Soft terminal reset (DECSTR). + // CSI Ps$ p + // Request ANSI mode (DECRQM). + // CSI ? Ps$ p + // Request DEC private mode (DECRQM). + // CSI Ps ; Ps " p + case 'p': + switch (this.prefix) { + // case '>': + // this.setPointerMode(this.params); + // break; + case '!': + this.softReset(this.params); + break; + // case '?': + // if (this.postfix === '$') { + // this.requestPrivateMode(this.params); + // } + // break; + // default: + // if (this.postfix === '"') { + // this.setConformanceLevel(this.params); + // } else if (this.postfix === '$') { + // this.requestAnsiMode(this.params); + // } + // break; + } + break; + + // CSI Ps q Load LEDs (DECLL). + // CSI Ps SP q + // CSI Ps " q + // case 'q': + // if (this.postfix === ' ') { + // this.setCursorStyle(this.params); + // break; + // } + // if (this.postfix === '"') { + // this.setCharProtectionAttr(this.params); + // break; + // } + // this.loadLEDs(this.params); + // break; + + // CSI Ps ; Ps r + // Set Scrolling Region [top;bottom] (default = full size of win- + // dow) (DECSTBM). + // CSI ? Pm r + // CSI Pt; Pl; Pb; Pr; Ps$ r + // case 'r': // duplicate + // if (this.prefix === '?') { + // this.restorePrivateValues(this.params); + // } else if (this.postfix === '$') { + // this.setAttrInRectangle(this.params); + // } else { + // this.setScrollRegion(this.params); + // } + // break; + + // CSI s Save cursor (ANSI.SYS). + // CSI ? Pm s + // case 's': // duplicate + // if (this.prefix === '?') { + // this.savePrivateValues(this.params); + // } else { + // this.saveCursor(this.params); + // } + // break; + + // CSI Ps ; Ps ; Ps t + // CSI Pt; Pl; Pb; Pr; Ps$ t + // CSI > Ps; Ps t + // CSI Ps SP t + // case 't': + // if (this.postfix === '$') { + // this.reverseAttrInRectangle(this.params); + // } else if (this.postfix === ' ') { + // this.setWarningBellVolume(this.params); + // } else { + // if (this.prefix === '>') { + // this.setTitleModeFeature(this.params); + // } else { + // this.manipulateWindow(this.params); + // } + // } + // break; + + // CSI u Restore cursor (ANSI.SYS). + // CSI Ps SP u + // case 'u': // duplicate + // if (this.postfix === ' ') { + // this.setMarginBellVolume(this.params); + // } else { + // this.restoreCursor(this.params); + // } + // break; + + // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v + // case 'v': + // if (this.postfix === '$') { + // this.copyRectagle(this.params); + // } + // break; + + // CSI Pt ; Pl ; Pb ; Pr ' w + // case 'w': + // if (this.postfix === '\'') { + // this.enableFilterRectangle(this.params); + // } + // break; + + // CSI Ps x Request Terminal Parameters (DECREQTPARM). + // CSI Ps x Select Attribute Change Extent (DECSACE). + // CSI Pc; Pt; Pl; Pb; Pr$ x + // case 'x': + // if (this.postfix === '$') { + // this.fillRectangle(this.params); + // } else { + // this.requestParameters(this.params); + // //this.__(this.params); + // } + // break; + + // CSI Ps ; Pu ' z + // CSI Pt; Pl; Pb; Pr$ z + // case 'z': + // if (this.postfix === '\'') { + // this.enableLocatorReporting(this.params); + // } else if (this.postfix === '$') { + // this.eraseRectangle(this.params); + // } + // break; + + // CSI Pm ' { + // CSI Pt; Pl; Pb; Pr$ { + // case '{': + // if (this.postfix === '\'') { + // this.setLocatorEvents(this.params); + // } else if (this.postfix === '$') { + // this.selectiveEraseRectangle(this.params); + // } + // break; + + // CSI Ps ' | + // case '|': + // if (this.postfix === '\'') { + // this.requestLocatorPosition(this.params); + // } + // break; + + // CSI P m SP } + // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. + // case '}': + // if (this.postfix === ' ') { + // this.insertColumns(this.params); + // } + // break; + + // CSI P m SP ~ + // Delete P s Column(s) (default = 1) (DECDC), VT420 and up + // case '~': + // if (this.postfix === ' ') { + // this.deleteColumns(this.params); + // } + // break; + default: - this.error('Unknown DCS prefix: %s.', this.prefix); + this.error('Unknown CSI code: %s.', ch); break; } - this.currentParam = 0; this.prefix = ''; - this.state = normal; - } else if (!this.currentParam) { - if (!this.prefix && ch !== '$' && ch !== '+') { - this.currentParam = ch; - } else if (this.prefix.length === 2) { - this.currentParam = ch; + this.postfix = ''; + break; + + case dcs: + if (ch === '\x1b' || ch === '\x07') { + if (ch === '\x1b') i++; + + switch (this.prefix) { + // User-Defined Keys (DECUDK). + case '': + break; + + // Request Status String (DECRQSS). + // test: echo -e '\eP$q"p\e\\' + case '$q': + var pt = this.currentParam + , valid = false; + + switch (pt) { + // DECSCA + case '"q': + pt = '0"q'; + break; + + // DECSCL + case '"p': + pt = '61"p'; + break; + + // DECSTBM + case 'r': + pt = '' + + (this.scrollTop + 1) + + ';' + + (this.scrollBottom + 1) + + 'r'; + break; + + // SGR + case 'm': + pt = '0m'; + break; + + default: + this.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + + this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\'); + break; + + // Set Termcap/Terminfo Data (xterm, experimental). + case '+p': + break; + + // Request Termcap/Terminfo String (xterm, experimental) + // Regular xterm does not even respond to this sequence. + // This can cause a small glitch in vim. + // test: echo -ne '\eP+q6b64\e\\' + case '+q': + var pt = this.currentParam + , valid = false; + + this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\'); + break; + + default: + this.error('Unknown DCS prefix: %s.', this.prefix); + break; + } + + this.currentParam = 0; + this.prefix = ''; + this.state = normal; + } else if (!this.currentParam) { + if (!this.prefix && ch !== '$' && ch !== '+') { + this.currentParam = ch; + } else if (this.prefix.length === 2) { + this.currentParam = ch; + } else { + this.prefix += ch; + } } else { - this.prefix += ch; + this.currentParam += ch; } - } else { - this.currentParam += ch; - } - break; + break; - case ignore: - // For PM and APC. - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') i++; - this.state = normal; - } - break; + case ignore: + // For PM and APC. + if (ch === '\x1b' || ch === '\x07') { + if (ch === '\x1b') i++; + this.state = normal; + } + break; + } } + + this.updateRange(this.y); + this.queueRefresh(this.refreshStart, this.refreshEnd); } - - this.updateRange(this.y); - this.queueRefresh(this.refreshStart, this.refreshEnd); - - if (this.writeBuffer.length > 0) { - var self = this; - -// TODO: async makes this too slow, need to change to iterative to prevent potential stack overflow - - // Start a new async innerWrite to prevent a stack overflow - //setTimeout(function () { - self.innerWrite(self.writeBuffer.shift()); - //}); - } else { - this.writeInProgress = false; - } + this.writeInProgress = false; }; /** From 0ec7b661f2be4660821301942cfe175c89f6f40f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 15:38:14 -0800 Subject: [PATCH 007/211] Tweak config values --- src/xterm.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 0849775d..29a38487 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -42,13 +42,13 @@ var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6; * pty process. This number must be small in order for ^C and similar sequences * to be responsive. */ -var WRITE_BUFFER_PAUSE_THRESHOLD = 0; +var WRITE_BUFFER_PAUSE_THRESHOLD = 2; /** * The maximum number of refresh frames to skip when the write buffer is non- * empty. */ -var MAX_REFRESH_FRAME_SKIP = 6; +var MAX_REFRESH_FRAME_SKIP = 5; /** * Terminal @@ -1384,7 +1384,7 @@ Terminal.prototype.write = function(data) { // Send XOFF to pause the pty process if the write buffer becomes too large so // xterm.js can catch up before more data is sent. This is necessary in order // to keep signals such as ^C responsive. - if (!this.xoffSentToCatchUp && this.writeBuffer.length > WRITE_BUFFER_PAUSE_THRESHOLD) { + if (!this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { // XOFF - stop pty pipe // XON will be triggered by emulator before processing data chunk this.send('\x13'); From 2b8820fdac9170388a6018270021ad74b7c324f1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 3 Jan 2017 15:52:45 -0800 Subject: [PATCH 008/211] Further tweaks, add write batching --- src/xterm.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 29a38487..038969ae 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -42,11 +42,18 @@ var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6; * pty process. This number must be small in order for ^C and similar sequences * to be responsive. */ -var WRITE_BUFFER_PAUSE_THRESHOLD = 2; +var WRITE_BUFFER_PAUSE_THRESHOLD = 5; + +/** + * The number of writes to perform in a single batch before allowing the + * renderer to catch up with a 0ms setTimeout. + */ +var WRITE_BATCH_SIZE = 300; /** * The maximum number of refresh frames to skip when the write buffer is non- - * empty. + * empty. Note that these frames may be intermingled with frames that are + * skipped via requestAnimationFrame's mechanism. */ var MAX_REFRESH_FRAME_SKIP = 5; @@ -1403,13 +1410,14 @@ Terminal.prototype.write = function(data) { } Terminal.prototype.innerWrite = function() { - while (this.writeBuffer.length > 0) { - var data = this.writeBuffer.shift(); + var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); + while (writeBatch.length > 0) { + var data = writeBatch.shift(); var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; // If XOFF was sent in order to catch up with the pty process, resume it if // the writeBuffer is empty to allow more data to come in. - if (this.xoffSentToCatchUp && this.writeBuffer.length === 0) { + if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) { this.send('\x11'); this.xoffSentToCatchUp = false; } @@ -2452,7 +2460,15 @@ Terminal.prototype.innerWrite = function() { this.updateRange(this.y); this.queueRefresh(this.refreshStart, this.refreshEnd); } - this.writeInProgress = false; + if (this.writeBuffer.length > 0) { + // Allow renderer to catch up before processing the next batch + var self = this; + setTimeout(function () { + self.innerWrite(); + }, 0); + } else { + this.writeInProgress = false; + } }; /** From 94c01ec378c9506414222fd01af2244885fcb7af Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 4 Jan 2017 08:08:59 -0800 Subject: [PATCH 009/211] Fix tests --- src/test/escape-sequences-test.js | 6 +++++- src/test/test.js | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index ace2c3cb..e9183ccf 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -92,7 +92,11 @@ describe('xterm output comparison', function() { var from_pty = pty_write_read(in_file); // uncomment this to get log from terminal //console.log = function(){}; - xterm.write(from_pty); + + // Perform a synchronous .write(data) + xterm.writeBuffer.push(from_pty); + xterm.innerWrite(); + var from_emulator = terminalToString(xterm); console.log = CONSOLE_LOG; var expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8'); diff --git a/src/test/test.js b/src/test/test.js index a44d2066..7c716b2a 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -14,6 +14,15 @@ describe('xterm.js', function() { xterm.compositionHelper = { keydown: function(){ return true; } }; + // Force synchronous refreshes + xterm.queueRefresh = function(start, end) { + xterm.refresh(start, end); + }; + // Force synchronous writes + xterm.write = function(data) { + xterm.writeBuffer.push(data); + xterm.innerWrite(); + }; }); describe('getOption', function() { From d9d60063d788308c98a2809e6b5086e64aa27bcc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 4 Jan 2017 12:43:21 -0800 Subject: [PATCH 010/211] Add disableStdin option Fixes #452 --- src/xterm.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 1d220652..78c07609 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -326,7 +326,8 @@ Terminal.defaults = { scrollback: 1000, screenKeys: false, debug: false, - cancelEvents: false + cancelEvents: false, + disableStdin: false // programFeatures: false, // focusKeys: false, }; @@ -3134,6 +3135,11 @@ Terminal.prototype.is = function(term) { * @param {string} data The data to populate in the event. */ Terminal.prototype.handler = function(data) { + // Prevents all events to pty process if stdin is disabled + if (this.options.disableStdin) { + return; + } + // Input is being sent to the terminal, the terminal should focus the prompt. if (this.ybase !== this.ydisp) { this.scrollToBottom(); From bebe43e5e108b081a8ead57b881e7ea1504164d7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 8 Jan 2017 13:33:51 -0800 Subject: [PATCH 011/211] Use node-pty as it's been published --- demo/app.js | 2 +- package.json | 2 +- src/test/escape-sequences-test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/app.js b/demo/app.js index a4122ace..3439ea99 100644 --- a/demo/app.js +++ b/demo/app.js @@ -2,7 +2,7 @@ var express = require('express'); var app = express(); var expressWs = require('express-ws')(app); var os = require('os'); -var pty = require('pty.js'); +var pty = require('node-pty'); var terminals = {}, logs = {}; diff --git a/package.json b/package.json index 6df2314a..74ba3e00 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,8 @@ "glob": "^7.0.5", "jsdoc": "3.4.3", "mocha": "2.5.3", + "node-pty": "^0.4.1", "nodemon": "1.10.2", - "pty.js": "https://github.com/Tyriar/pty.js/tarball/c75c2dcb6dcad83b0cb3ef2ae42d0448fb912642", "sleep": "^3.0.1", "sorcery": "^0.10.0", "tslint": "^4.0.2", diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index ace2c3cb..7dcefd95 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -1,6 +1,6 @@ var glob = require('glob'); var fs = require('fs'); -var pty = require('pty.js'); +var pty = require('node-pty'); var sleep = require('sleep'); var Terminal = require('../xterm'); From 3de3c0c6b69f9b3e836d57c4f08a3f716f1d110e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 8 Jan 2017 15:49:19 -0800 Subject: [PATCH 012/211] Pull C0 escape sequences into its own file Part of #460 --- src/EscapeSequences.ts | 74 +++++++++++++++ src/xterm.js | 204 ++++++++++++++++++++--------------------- 2 files changed, 176 insertions(+), 102 deletions(-) create mode 100644 src/EscapeSequences.ts diff --git a/src/EscapeSequences.ts b/src/EscapeSequences.ts new file mode 100644 index 00000000..d4b736fd --- /dev/null +++ b/src/EscapeSequences.ts @@ -0,0 +1,74 @@ +/** + * C0 control codes + * See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes + */ +export const C0 = { + /** Null (Caret: ^@, C: \0) */ + NUL: '\x00', + /** Start of Heading (Caret: ^A) */ + SOH: '\x01', + /** Start of Text (Caret: ^B) */ + STX: '\x02', + /** End of Text (Caret: ^C) */ + ETX: '\x03', + /** End of Transmission (Caret: ^D) */ + EOT: '\x04', + /** Enquiry (Caret: ^E) */ + ENQ: '\x05', + /** Acknowledge (Caret: ^F) */ + ACK: '\x06', + /** Bell (Caret: ^G, C: \a) */ + BEL: '\x07', + /** Backspace (Caret: ^H, C: \b) */ + BS: '\x08', + /** Character Tabulation, Horizontal Tabulation (Caret: ^I, C: \t) */ + HT: '\x09', + /** Line Feed (Caret: ^J, C: \n) */ + LF: '\x0a', + /** Line Tabulation, Vertical Tabulation (Caret: ^K, C: \v) */ + VT: '\x0b', + /** Form Feed (Caret: ^L, C: \f) */ + FF: '\x0c', + /** Carriage Return (Caret: ^M, C: \r) */ + CR: '\x0d', + /** Shift Out (Caret: ^N) */ + SO: '\x0e', + /** Shift In (Caret: ^O) */ + SI: '\x0f', + /** Data Link Escape (Caret: ^P) */ + DLE: '\x10', + /** Device Control One (XON) (Caret: ^Q) */ + DC1: '\x11', + /** Device Control Two (Caret: ^R) */ + DC2: '\x12', + /** Device Control Three (XOFF) (Caret: ^S) */ + DC3: '\x13', + /** Device Control Four (Caret: ^T) */ + DC4: '\x14', + /** Negative Acknowledge (Caret: ^U) */ + NAK: '\x15', + /** Synchronous Idle (Caret: ^V) */ + SYN: '\x16', + /** End of Transmission Block (Caret: ^W) */ + ETB: '\x17', + /** Cancel (Caret: ^X) */ + CAN: '\x18', + /** End of Medium (Caret: ^Y) */ + EM: '\x19', + /** Substitute (Caret: ^Z) */ + SUB: '\x1a', + /** Escape (Caret: ^[, C: \e) */ + ESC: '\x1b', + /** File Separator (Caret: ^\) */ + FS: '\x1c', + /** Group Separator (Caret: ^]) */ + GS: '\x1d', + /** Record Separator (Caret: ^^) */ + RS: '\x1e', + /** Unit Separator (Caret: ^_) */ + US: '\x1f', + /** Space */ + SP: '\x20', + /** Delete (Caret: ^?) */ + DEL: '\x7f' +}; diff --git a/src/xterm.js b/src/xterm.js index 1d220652..0d9e1ca8 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -15,6 +15,7 @@ import { EventEmitter } from './EventEmitter.js'; import { Viewport } from './Viewport.js'; import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js'; import { CircularList } from './utils/CircularList.js'; +import { C0 } from './EscapeSequences'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -384,7 +385,7 @@ Terminal.prototype.setOption = function(key, value) { Terminal.bindFocus = function (term) { on(term.textarea, 'focus', function (ev) { if (term.sendFocus) { - term.send('\x1b[I'); + term.send(C0.ESC + '[I'); } term.element.classList.add('focus'); term.showCursor(); @@ -409,7 +410,7 @@ Terminal.bindBlur = function (term) { on(term.textarea, 'blur', function (ev) { term.refresh(term.y, term.y); if (term.sendFocus) { - term.send('\x1b[O'); + term.send(C0.ESC + '[O'); } term.element.classList.remove('focus'); Terminal.focus = null; @@ -742,7 +743,7 @@ Terminal.prototype.bindMouse = function() { button &= 3; pos.x -= 32; pos.y -= 32; - var data = '\x1b[24'; + var data = C0.ESC + '[24'; if (button === 0) data += '1'; else if (button === 1) data += '3'; else if (button === 2) data += '5'; @@ -762,7 +763,7 @@ Terminal.prototype.bindMouse = function() { else if (button === 1) button = 4; else if (button === 2) button = 6; else if (button === 3) button = 3; - self.send('\x1b[' + self.send(C0.ESC + '[' + button + ';' + (button === 3 ? 4 : 0) @@ -781,14 +782,14 @@ Terminal.prototype.bindMouse = function() { pos.y -= 32; pos.x++; pos.y++; - self.send('\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M'); + self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M'); return; } if (self.sgrMouse) { pos.x -= 32; pos.y -= 32; - self.send('\x1b[<' + self.send(C0.ESC + '[<' + (((button & 3) === 3 ? button & ~3 : button) - 32) + ';' + pos.x @@ -804,7 +805,7 @@ Terminal.prototype.bindMouse = function() { encode(data, pos.x); encode(data, pos.y); - self.send('\x1b[M' + String.fromCharCode.apply(String, data)); + self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data)); } function getButton(ev) { @@ -1376,14 +1377,13 @@ Terminal.prototype.write = function(data) { switch (this.state) { case normal: switch (ch) { - case '\x07': + case C0.BEL: this.bell(); break; - // '\n', '\v', '\f' - case '\n': - case '\x0b': - case '\x0c': + case C0.LF: + case C0.VT: + case C0.FF: if (this.convertEol) { this.x = 0; } @@ -1395,34 +1395,34 @@ Terminal.prototype.write = function(data) { break; // '\r' - case '\r': + case C0.CR: this.x = 0; break; // '\b' - case '\x08': + case C0.BS: if (this.x > 0) { this.x--; } break; // '\t' - case '\t': + case C0.HT: this.x = this.nextStop(); break; // shift out - case '\x0e': + case C0.SO: this.setgLevel(1); break; // shift in - case '\x0f': + case C0.SI: this.setgLevel(0); break; // '\e' - case '\x1b': + case C0.ESC: this.state = escaped; break; @@ -1751,8 +1751,8 @@ Terminal.prototype.write = function(data) { // OSC Ps ; Pt ST // OSC Ps ; Pt BEL // Set Text Parameters. - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') i++; + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) i++; this.params.push(this.currentParam); @@ -2284,8 +2284,8 @@ Terminal.prototype.write = function(data) { break; case dcs: - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') i++; + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) i++; switch (this.prefix) { // User-Defined Keys (DECUDK). @@ -2329,7 +2329,7 @@ Terminal.prototype.write = function(data) { break; } - this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\'); + this.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\'); break; // Set Termcap/Terminfo Data (xterm, experimental). @@ -2344,7 +2344,7 @@ Terminal.prototype.write = function(data) { var pt = this.currentParam , valid = false; - this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\'); + this.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\'); break; default: @@ -2370,8 +2370,8 @@ Terminal.prototype.write = function(data) { case ignore: // For PM and APC. - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') i++; + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) i++; this.state = normal; } break; @@ -2471,90 +2471,90 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) { case 8: // backspace if (ev.shiftKey) { - result.key = '\x08'; // ^H + result.key = C0.BS; // ^H break; } - result.key = '\x7f'; // ^? + result.key = C0.DEL; // ^? break; case 9: // tab if (ev.shiftKey) { - result.key = '\x1b[Z'; + result.key = C0.ESC + '[Z'; break; } - result.key = '\t'; + result.key = C0.HT; result.cancel = true; break; case 13: // return/enter - result.key = '\r'; + result.key = C0.CR; result.cancel = true; break; case 27: // escape - result.key = '\x1b'; + result.key = C0.ESC; result.cancel = true; break; case 37: // left-arrow if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'D'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D'; // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards // http://unix.stackexchange.com/a/108106 // macOS uses different escape sequences than linux - if (result.key == '\x1b[1;3D') { - result.key = (this.browser.isMac) ? '\x1bb' : '\x1b[1;5D'; + if (result.key == C0.ESC + '[1;3D') { + result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D'; } } else if (this.applicationCursor) { - result.key = '\x1bOD'; + result.key = C0.ESC + 'OD'; } else { - result.key = '\x1b[D'; + result.key = C0.ESC + '[D'; } break; case 39: // right-arrow if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'C'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C'; // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward // http://unix.stackexchange.com/a/108106 // macOS uses different escape sequences than linux - if (result.key == '\x1b[1;3C') { - result.key = (this.browser.isMac) ? '\x1bf' : '\x1b[1;5C'; + if (result.key == C0.ESC + '[1;3C') { + result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C'; } } else if (this.applicationCursor) { - result.key = '\x1bOC'; + result.key = C0.ESC + 'OC'; } else { - result.key = '\x1b[C'; + result.key = C0.ESC + '[C'; } break; case 38: // up-arrow if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'A'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A'; // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow // http://unix.stackexchange.com/a/108106 - if (result.key == '\x1b[1;3A') { - result.key = '\x1b[1;5A'; + if (result.key == C0.ESC + '[1;3A') { + result.key = C0.ESC + '[1;5A'; } } else if (this.applicationCursor) { - result.key = '\x1bOA'; + result.key = C0.ESC + 'OA'; } else { - result.key = '\x1b[A'; + result.key = C0.ESC + '[A'; } break; case 40: // down-arrow if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'B'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B'; // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow // http://unix.stackexchange.com/a/108106 - if (result.key == '\x1b[1;3B') { - result.key = '\x1b[1;5B'; + if (result.key == C0.ESC + '[1;3B') { + result.key = C0.ESC + '[1;5B'; } } else if (this.applicationCursor) { - result.key = '\x1bOB'; + result.key = C0.ESC + 'OB'; } else { - result.key = '\x1b[B'; + result.key = C0.ESC + '[B'; } break; case 45: @@ -2562,41 +2562,41 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) { if (!ev.shiftKey && !ev.ctrlKey) { // or + are used to // copy-paste on some systems. - result.key = '\x1b[2~'; + result.key = C0.ESC + '[2~'; } break; case 46: // delete if (modifiers) { - result.key = '\x1b[3;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[3;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[3~'; + result.key = C0.ESC + '[3~'; } break; case 36: // home if (modifiers) - result.key = '\x1b[1;' + (modifiers + 1) + 'H'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H'; else if (this.applicationCursor) - result.key = '\x1bOH'; + result.key = C0.ESC + 'OH'; else - result.key = '\x1b[H'; + result.key = C0.ESC + '[H'; break; case 35: // end if (modifiers) - result.key = '\x1b[1;' + (modifiers + 1) + 'F'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F'; else if (this.applicationCursor) - result.key = '\x1bOF'; + result.key = C0.ESC + 'OF'; else - result.key = '\x1b[F'; + result.key = C0.ESC + '[F'; break; case 33: // page up if (ev.shiftKey) { result.scrollDisp = -(this.rows - 1); } else { - result.key = '\x1b[5~'; + result.key = C0.ESC + '[5~'; } break; case 34: @@ -2604,92 +2604,92 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) { if (ev.shiftKey) { result.scrollDisp = this.rows - 1; } else { - result.key = '\x1b[6~'; + result.key = C0.ESC + '[6~'; } break; case 112: // F1-F12 if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'P'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P'; } else { - result.key = '\x1bOP'; + result.key = C0.ESC + 'OP'; } break; case 113: if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'Q'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q'; } else { - result.key = '\x1bOQ'; + result.key = C0.ESC + 'OQ'; } break; case 114: if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'R'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R'; } else { - result.key = '\x1bOR'; + result.key = C0.ESC + 'OR'; } break; case 115: if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'S'; + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S'; } else { - result.key = '\x1bOS'; + result.key = C0.ESC + 'OS'; } break; case 116: if (modifiers) { - result.key = '\x1b[15;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[15;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[15~'; + result.key = C0.ESC + '[15~'; } break; case 117: if (modifiers) { - result.key = '\x1b[17;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[17;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[17~'; + result.key = C0.ESC + '[17~'; } break; case 118: if (modifiers) { - result.key = '\x1b[18;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[18;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[18~'; + result.key = C0.ESC + '[18~'; } break; case 119: if (modifiers) { - result.key = '\x1b[19;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[19;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[19~'; + result.key = C0.ESC + '[19~'; } break; case 120: if (modifiers) { - result.key = '\x1b[20;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[20;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[20~'; + result.key = C0.ESC + '[20~'; } break; case 121: if (modifiers) { - result.key = '\x1b[21;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[21;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[21~'; + result.key = C0.ESC + '[21~'; } break; case 122: if (modifiers) { - result.key = '\x1b[23;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[23;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[23~'; + result.key = C0.ESC + '[23~'; } break; case 123: if (modifiers) { - result.key = '\x1b[24;' + (modifiers + 1) + '~'; + result.key = C0.ESC + '[24;' + (modifiers + 1) + '~'; } else { - result.key = '\x1b[24~'; + result.key = C0.ESC + '[24~'; } break; default: @@ -2719,11 +2719,11 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) { } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { // On Mac this is a third level shift. Use instead. if (ev.keyCode >= 65 && ev.keyCode <= 90) { - result.key = '\x1b' + String.fromCharCode(ev.keyCode + 32); + result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32); } else if (ev.keyCode === 192) { - result.key = '\x1b`'; + result.key = C0.ESC + '`'; } else if (ev.keyCode >= 48 && ev.keyCode <= 57) { - result.key = '\x1b' + (ev.keyCode - 48); + result.key = C0.ESC + (ev.keyCode - 48); } } break; @@ -3583,11 +3583,11 @@ Terminal.prototype.deviceStatus = function(params) { switch (params[0]) { case 5: // status report - this.send('\x1b[0n'); + this.send(C0.ESC + '[0n'); break; case 6: // cursor position - this.send('\x1b[' + this.send(C0.ESC + '[' + (this.y + 1) + ';' + (this.x + 1) @@ -3600,7 +3600,7 @@ Terminal.prototype.deviceStatus = function(params) { switch (params[0]) { case 6: // cursor position - this.send('\x1b[?' + this.send(C0.ESC + '[?' + (this.y + 1) + ';' + (this.x + 1) @@ -3608,19 +3608,19 @@ Terminal.prototype.deviceStatus = function(params) { break; case 15: // no printer - // this.send('\x1b[?11n'); + // this.send(C0.ESC + '[?11n'); break; case 25: // dont support user defined keys - // this.send('\x1b[?21n'); + // this.send(C0.ESC + '[?21n'); break; case 26: // north american keyboard - // this.send('\x1b[?27;1;0;0n'); + // this.send(C0.ESC + '[?27;1;0;0n'); break; case 53: // no dec locator/mouse - // this.send('\x1b[?50n'); + // this.send(C0.ESC + '[?50n'); break; } } @@ -3871,24 +3871,24 @@ Terminal.prototype.sendDeviceAttributes = function(params) { if (this.is('xterm') || this.is('rxvt-unicode') || this.is('screen')) { - this.send('\x1b[?1;2c'); + this.send(C0.ESC + '[?1;2c'); } else if (this.is('linux')) { - this.send('\x1b[?6c'); + this.send(C0.ESC + '[?6c'); } } else if (this.prefix === '>') { // xterm and urxvt // seem to spit this // out around ~370 times (?). if (this.is('xterm')) { - this.send('\x1b[>0;276;0c'); + this.send(C0.ESC + '[>0;276;0c'); } else if (this.is('rxvt-unicode')) { - this.send('\x1b[>85;95;0c'); + this.send(C0.ESC + '[>85;95;0c'); } else if (this.is('linux')) { // not supported by linux console. // linux console echoes parameters. this.send(params[0] + 'c'); } else if (this.is('screen')) { - this.send('\x1b[>83;40003;0c'); + this.send(C0.ESC + '[>83;40003;0c'); } } }; From 1685cf2d8f4902c65da5f07475a7fd37252d420d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 8 Jan 2017 16:02:47 -0800 Subject: [PATCH 013/211] Use namespace and const for C0 constants --- src/EscapeSequences.ts | 138 ++++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/EscapeSequences.ts b/src/EscapeSequences.ts index d4b736fd..34dfde90 100644 --- a/src/EscapeSequences.ts +++ b/src/EscapeSequences.ts @@ -1,74 +1,74 @@ /** * C0 control codes - * See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes + * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes */ -export const C0 = { - /** Null (Caret: ^@, C: \0) */ - NUL: '\x00', - /** Start of Heading (Caret: ^A) */ - SOH: '\x01', - /** Start of Text (Caret: ^B) */ - STX: '\x02', - /** End of Text (Caret: ^C) */ - ETX: '\x03', - /** End of Transmission (Caret: ^D) */ - EOT: '\x04', - /** Enquiry (Caret: ^E) */ - ENQ: '\x05', - /** Acknowledge (Caret: ^F) */ - ACK: '\x06', - /** Bell (Caret: ^G, C: \a) */ - BEL: '\x07', - /** Backspace (Caret: ^H, C: \b) */ - BS: '\x08', - /** Character Tabulation, Horizontal Tabulation (Caret: ^I, C: \t) */ - HT: '\x09', - /** Line Feed (Caret: ^J, C: \n) */ - LF: '\x0a', - /** Line Tabulation, Vertical Tabulation (Caret: ^K, C: \v) */ - VT: '\x0b', - /** Form Feed (Caret: ^L, C: \f) */ - FF: '\x0c', - /** Carriage Return (Caret: ^M, C: \r) */ - CR: '\x0d', - /** Shift Out (Caret: ^N) */ - SO: '\x0e', - /** Shift In (Caret: ^O) */ - SI: '\x0f', - /** Data Link Escape (Caret: ^P) */ - DLE: '\x10', - /** Device Control One (XON) (Caret: ^Q) */ - DC1: '\x11', - /** Device Control Two (Caret: ^R) */ - DC2: '\x12', - /** Device Control Three (XOFF) (Caret: ^S) */ - DC3: '\x13', - /** Device Control Four (Caret: ^T) */ - DC4: '\x14', - /** Negative Acknowledge (Caret: ^U) */ - NAK: '\x15', - /** Synchronous Idle (Caret: ^V) */ - SYN: '\x16', - /** End of Transmission Block (Caret: ^W) */ - ETB: '\x17', - /** Cancel (Caret: ^X) */ - CAN: '\x18', - /** End of Medium (Caret: ^Y) */ - EM: '\x19', - /** Substitute (Caret: ^Z) */ - SUB: '\x1a', - /** Escape (Caret: ^[, C: \e) */ - ESC: '\x1b', - /** File Separator (Caret: ^\) */ - FS: '\x1c', - /** Group Separator (Caret: ^]) */ - GS: '\x1d', - /** Record Separator (Caret: ^^) */ - RS: '\x1e', - /** Unit Separator (Caret: ^_) */ - US: '\x1f', +export namespace C0 { + /** Null (Caret = ^@, C = \0) */ + export const NUL = '\x00'; + /** Start of Heading (Caret = ^A) */ + export const SOH = '\x01'; + /** Start of Text (Caret = ^B) */ + export const STX = '\x02'; + /** End of Text (Caret = ^C) */ + export const ETX = '\x03'; + /** End of Transmission (Caret = ^D) */ + export const EOT = '\x04'; + /** Enquiry (Caret = ^E) */ + export const ENQ = '\x05'; + /** Acknowledge (Caret = ^F) */ + export const ACK = '\x06'; + /** Bell (Caret = ^G, C = \a) */ + export const BEL = '\x07'; + /** Backspace (Caret = ^H, C = \b) */ + export const BS = '\x08'; + /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \t) */ + export const HT = '\x09'; + /** Line Feed (Caret = ^J, C = \n) */ + export const LF = '\x0a'; + /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \v) */ + export const VT = '\x0b'; + /** Form Feed (Caret = ^L, C = \f) */ + export const FF = '\x0c'; + /** Carriage Return (Caret = ^M, C = \r) */ + export const CR = '\x0d'; + /** Shift Out (Caret = ^N) */ + export const SO = '\x0e'; + /** Shift In (Caret = ^O) */ + export const SI = '\x0f'; + /** Data Link Escape (Caret = ^P) */ + export const DLE = '\x10'; + /** Device Control One (XON) (Caret = ^Q) */ + export const DC1 = '\x11'; + /** Device Control Two (Caret = ^R) */ + export const DC2 = '\x12'; + /** Device Control Three (XOFF) (Caret = ^S) */ + export const DC3 = '\x13'; + /** Device Control Four (Caret = ^T) */ + export const DC4 = '\x14'; + /** Negative Acknowledge (Caret = ^U) */ + export const NAK = '\x15'; + /** Synchronous Idle (Caret = ^V) */ + export const SYN = '\x16'; + /** End of Transmission Block (Caret = ^W) */ + export const ETB = '\x17'; + /** Cancel (Caret = ^X) */ + export const CAN = '\x18'; + /** End of Medium (Caret = ^Y) */ + export const EM = '\x19'; + /** Substitute (Caret = ^Z) */ + export const SUB = '\x1a'; + /** Escape (Caret = ^[, C = \e) */ + export const ESC = '\x1b'; + /** File Separator (Caret = ^\) */ + export const FS = '\x1c'; + /** Group Separator (Caret = ^]) */ + export const GS = '\x1d'; + /** Record Separator (Caret = ^^) */ + export const RS = '\x1e'; + /** Unit Separator (Caret = ^_) */ + export const US = '\x1f'; /** Space */ - SP: '\x20', - /** Delete (Caret: ^?) */ - DEL: '\x7f' + export const SP = '\x20'; + /** Delete (Caret = ^?) */ + export const DEL = '\x7f'; }; From 04b1ebf1a7b8a4b99a7a2fa3919a35b14bb14199 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 8 Jan 2017 16:11:35 -0800 Subject: [PATCH 014/211] Create InputHandler which performs C0 actions Part of #459 --- src/InputHandler.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/Interfaces.ts | 13 ++++++++++++ src/xterm.js | 26 +++++++++-------------- 3 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 src/InputHandler.ts diff --git a/src/InputHandler.ts b/src/InputHandler.ts new file mode 100644 index 00000000..38b85367 --- /dev/null +++ b/src/InputHandler.ts @@ -0,0 +1,50 @@ +import { IInputHandler, ITerminal } from './Interfaces'; + +export class InputHandler implements IInputHandler { + // TODO: We want to type _terminal when it's pulled into TS + constructor(private _terminal: any) { } + + public bell(): void { + if (!this._terminal.visualBell) { + return; + } + this._terminal.element.style.borderColor = 'white'; + setTimeout(() => this._terminal.element.style.borderColor = '', 10); + if (this._terminal.popOnBell) { + this._terminal.focus(); + } + } + + public lineFeed(): void { + if (this._terminal.convertEol) { + this._terminal.x = 0; + } + this._terminal.y++; + if (this._terminal.y > this._terminal.scrollBottom) { + this._terminal.y--; + this._terminal.scroll(); + } + } + + public carriageReturn(): void { + this._terminal.x = 0; + } + + public backspace(): void { + if (this._terminal.x > 0) { + this._terminal.x--; + } + } + + public tab(): void { + this._terminal.x = this._terminal.nextStop(); + } + + public shiftOut(): void { + this._terminal.setgLevel(1); + } + + public shiftIn(): void { + this._terminal.setgLevel(0); + } +} diff --git a/src/Interfaces.ts b/src/Interfaces.ts index ff7bbef2..ae05c79f 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -32,3 +32,16 @@ export interface ITerminal { scrollDisp(disp: number, suppressScrollEvent: boolean); cancel(ev: Event, force?: boolean); } + +/** + * Handles actions generated by the parser. + */ +export interface IInputHandler { + bell(): void; + lineFeed(): void; + carriageReturn(): void; + backspace(): void; + tab(): void; + shiftOut(): void; + shiftIn(): void; +} diff --git a/src/xterm.js b/src/xterm.js index 0d9e1ca8..f33f0a9c 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -16,6 +16,7 @@ import { Viewport } from './Viewport.js'; import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js'; import { CircularList } from './utils/CircularList.js'; import { C0 } from './EscapeSequences'; +import { InputHandler } from './InputHandler'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -203,6 +204,8 @@ function Terminal(options) { this.prefix = ''; this.postfix = ''; + this.inputHandler = new InputHandler(this); + // leftover surrogate high from previous write invocation this.surrogate_high = ''; @@ -1378,47 +1381,38 @@ Terminal.prototype.write = function(data) { case normal: switch (ch) { case C0.BEL: - this.bell(); + this.inputHandler.bell(); break; case C0.LF: case C0.VT: case C0.FF: - if (this.convertEol) { - this.x = 0; - } - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); - } + this.inputHandler.lineFeed(); break; // '\r' case C0.CR: - this.x = 0; + this.inputHandler.carriageReturn(); break; // '\b' case C0.BS: - if (this.x > 0) { - this.x--; - } + this.inputHandler.backspace(); break; // '\t' case C0.HT: - this.x = this.nextStop(); + this.inputHandler.tab(); break; // shift out case C0.SO: - this.setgLevel(1); + this.inputHandler.shiftOut(); break; // shift in case C0.SI: - this.setgLevel(0); + this.inputHandler.shiftIn(); break; // '\e' From 659fb90c1c5d05ea286355e800365eb0b4176021 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 8 Jan 2017 16:21:51 -0800 Subject: [PATCH 015/211] Handle C0 codes via handler map in Parser --- src/Parser.ts | 12 ++++++++++++ src/xterm.js | 46 ++++++++++------------------------------------ 2 files changed, 22 insertions(+), 36 deletions(-) create mode 100644 src/Parser.ts diff --git a/src/Parser.ts b/src/Parser.ts new file mode 100644 index 00000000..666a9151 --- /dev/null +++ b/src/Parser.ts @@ -0,0 +1,12 @@ +import { C0 } from './EscapeSequences'; +import { IInputHandler } from './Interfaces'; + +export const normalStateHandler: {[key: string]: (handler: IInputHandler) => void} = {}; +normalStateHandler[C0.BEL] = (handler) => handler.bell(); +normalStateHandler[C0.LF] = (handler) => handler.lineFeed(); +normalStateHandler[C0.VT] = normalStateHandler[C0.LF]; +normalStateHandler[C0.FF] = normalStateHandler[C0.LF]; +normalStateHandler[C0.CR] = (handler) => handler.carriageReturn(); +normalStateHandler[C0.HT] = (handler) => handler.tab(); +normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); +normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); diff --git a/src/xterm.js b/src/xterm.js index f33f0a9c..7d70c268 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -17,6 +17,7 @@ import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboa import { CircularList } from './utils/CircularList.js'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; +import * as parser from './Parser'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -1377,45 +1378,18 @@ Terminal.prototype.write = function(data) { // surrogate low - already handled above if (0xDC00 <= code && code <= 0xDFFF) continue; + + if (this.state === normal) { + if (ch in parser.normalStateHandler) { + parser.normalStateHandler[ch](this.inputHandler); + // Skip switch statement (eventually everything will be handled this way + continue; + } + } + switch (this.state) { case normal: switch (ch) { - case C0.BEL: - this.inputHandler.bell(); - break; - - case C0.LF: - case C0.VT: - case C0.FF: - this.inputHandler.lineFeed(); - break; - - // '\r' - case C0.CR: - this.inputHandler.carriageReturn(); - break; - - // '\b' - case C0.BS: - this.inputHandler.backspace(); - break; - - // '\t' - case C0.HT: - this.inputHandler.tab(); - break; - - // shift out - case C0.SO: - this.inputHandler.shiftOut(); - break; - - // shift in - case C0.SI: - this.inputHandler.shiftIn(); - break; - - // '\e' case C0.ESC: this.state = escaped; break; From 665a11acc06789513b7f38fb2439576872bc5ed5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 8 Jan 2017 17:12:35 -0800 Subject: [PATCH 016/211] Add C0.BS handler back --- src/Parser.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Parser.ts b/src/Parser.ts index 666a9151..b878cedf 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -7,6 +7,7 @@ normalStateHandler[C0.LF] = (handler) => handler.lineFeed(); normalStateHandler[C0.VT] = normalStateHandler[C0.LF]; normalStateHandler[C0.FF] = normalStateHandler[C0.LF]; normalStateHandler[C0.CR] = (handler) => handler.carriageReturn(); +normalStateHandler[C0.BS] = (handler) => handler.backspace(); normalStateHandler[C0.HT] = (handler) => handler.tab(); normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); From 6c29ccfbd1ffc90ceca07130868322b5004af13a Mon Sep 17 00:00:00 2001 From: Tyler Jewell Date: Sun, 8 Jan 2017 17:41:02 -0800 Subject: [PATCH 017/211] Add Codenvy to the list of xTerm supporters --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 608c48ac..f68da0f1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Microsoft Visual Studio Code**](http://code.visualstudio.com/): Modern, versatile and powerful open source code editor that provides an integrated terminal based on xterm.js - [**ttyd**](https://github.com/tsl0922/ttyd): A command-line tool for sharing terminal over the web, with fully-featured terminal emulation based on xterm.js - [**Katacoda**](https://www.katacoda.com/): Katacoda is an Interactive Learning Platform for software developers, covering the latest Cloud Native technologies. -- [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE +- [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE. +- [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. @@ -120,7 +121,11 @@ Visit https://lair.io/sourcelair/xterm and follow the instructions. All developm #### [Eclipse Che](http://www.eclipse.org/che) -You can start Eclipse Che with `docker run eclipse/che start` +You can start Eclipse Che with `docker run eclipse/che start`. + +#### [Codenvy](http://www.codenvy.io) + +You can create a trial account or install an enterprise version with `docker run codenvy/cli start`. ## License Agreement From a31921ae735300e999e73e4986502a4ec48231f2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 13:45:55 -0800 Subject: [PATCH 018/211] Move parsing logic into Parser.ts --- src/Parser.ts | 1023 ++++++++++++++++++++++++++++++++++++++++++++- src/xterm.js | 1103 +------------------------------------------------ 2 files changed, 1025 insertions(+), 1101 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index b878cedf..517103d2 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1,7 +1,7 @@ import { C0 } from './EscapeSequences'; import { IInputHandler } from './Interfaces'; -export const normalStateHandler: {[key: string]: (handler: IInputHandler) => void} = {}; +const normalStateHandler: {[key: string]: (handler: IInputHandler) => void} = {}; normalStateHandler[C0.BEL] = (handler) => handler.bell(); normalStateHandler[C0.LF] = (handler) => handler.lineFeed(); normalStateHandler[C0.VT] = normalStateHandler[C0.LF]; @@ -11,3 +11,1024 @@ normalStateHandler[C0.BS] = (handler) => handler.backspace(); normalStateHandler[C0.HT] = (handler) => handler.tab(); normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); + +enum ParserState { + NORMAL = 0, + ESCAPED = 1, + CSI = 2, + OSC = 3, + CHARSET = 4, + DCS = 5, + IGNORE = 6 +} + +export class Parser { + private state: ParserState; + + // TODO: Remove terminal when handler can do everything + constructor( + private _inputHandler: IInputHandler, + private _terminal: any + ) { + this.state = ParserState.NORMAL; + } + + public parse(data: string) { + let l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; + + // apply leftover surrogate high from last write + if (this._terminal.surrogate_high) { + data = this._terminal.surrogate_high + data; + this._terminal.surrogate_high = ''; + } + + for (; i < l; i++) { + ch = data[i]; + + // FIXME: higher chars than 0xa0 are not allowed in escape sequences + // --> maybe move to default + code = data.charCodeAt(i); + if (0xD800 <= code && code <= 0xDBFF) { + // we got a surrogate high + // get surrogate low (next 2 bytes) + low = data.charCodeAt(i+1); + if (isNaN(low)) { + // end of data stream, save surrogate high + this._terminal.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(i+1); + } + // surrogate low - already handled above + if (0xDC00 <= code && code <= 0xDFFF) + continue; + + if (this.state === ParserState.NORMAL) { + if (ch in normalStateHandler) { + normalStateHandler[ch](this._inputHandler); + // Skip switch statement (eventually everything will be handled this way + continue; + } + } + + switch (this.state) { + case ParserState.NORMAL: + switch (ch) { + case C0.ESC: + this.state = ParserState.ESCAPED; + break; + + default: + // ' ' + // calculate print space + // expensive call, therefore we save width in line buffer + ch_width = wcwidth(code); + + if (ch >= ' ') { + if (this.charset && this.charset[ch]) { + ch = this.charset[ch]; + } + + row = this.y + this.ybase; + + // insert combining char in last cell + // FIXME: needs handling after cursor jumps + if (!ch_width && this.x) { + // dont overflow left + if (this.lines.get(row)[this.x-1]) { + if (!this.lines.get(row)[this.x-1][2]) { + + // found empty cell after fullwidth, need to go 2 cells back + if (this.lines.get(row)[this.x-2]) + this.lines.get(row)[this.x-2][1] += ch; + + } else { + this.lines.get(row)[this.x-1][1] += ch; + } + this.updateRange(this.y); + } + break; + } + + // goto next line if ch would overflow + // TODO: needs a global min terminal width of 2 + if (this.x+ch_width-1 >= this.cols) { + // autowrap - DECAWM + if (this.wraparoundMode) { + this.x = 0; + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } + } else { + this.x = this.cols-1; + if(ch_width===2) // FIXME: check for xterm behavior + continue; + } + } + row = this.y + this.ybase; + + // insert mode: move characters to right + if (this.insertMode) { + // do this twice for a fullwidth char + for (var moves=0; moves Normal Keypad (DECKPNM). + case '>': + this.log('Switching back to normal keypad.'); + this.applicationKeypad = false; + this.viewport.syncScrollArea(); + this.state = ParserState.NORMAL; + break; + + default: + this.state = ParserState.NORMAL; + this.error('Unknown ESC control: %s.', ch); + break; + } + break; + + case ParserState.CHARSET: + switch (ch) { + case '0': // DEC Special Character and Line Drawing Set. + cs = Terminal.charsets.SCLD; + break; + case 'A': // UK + cs = Terminal.charsets.UK; + break; + case 'B': // United States (USASCII). + cs = Terminal.charsets.US; + break; + case '4': // Dutch + cs = Terminal.charsets.Dutch; + break; + case 'C': // Finnish + case '5': + cs = Terminal.charsets.Finnish; + break; + case 'R': // French + cs = Terminal.charsets.French; + break; + case 'Q': // FrenchCanadian + cs = Terminal.charsets.FrenchCanadian; + break; + case 'K': // German + cs = Terminal.charsets.German; + break; + case 'Y': // Italian + cs = Terminal.charsets.Italian; + break; + case 'E': // NorwegianDanish + case '6': + cs = Terminal.charsets.NorwegianDanish; + break; + case 'Z': // Spanish + cs = Terminal.charsets.Spanish; + break; + case 'H': // Swedish + case '7': + cs = Terminal.charsets.Swedish; + break; + case '=': // Swiss + cs = Terminal.charsets.Swiss; + break; + case '/': // ISOLatin (actually /A) + cs = Terminal.charsets.ISOLatin; + i++; + break; + default: // Default + cs = Terminal.charsets.US; + break; + } + this.setgCharset(this.gcharset, cs); + this.gcharset = null; + this.state = ParserState.NORMAL; + break; + + case ParserState.OSC: + // OSC Ps ; Pt ST + // OSC Ps ; Pt BEL + // Set Text Parameters. + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) i++; + + this.params.push(this.currentParam); + + switch (this.params[0]) { + case 0: + case 1: + case 2: + if (this.params[1]) { + this.title = this.params[1]; + this.handleTitle(this.title); + } + break; + case 3: + // set X property + break; + case 4: + case 5: + // change dynamic colors + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + // change dynamic ui colors + break; + case 46: + // change log file + break; + case 50: + // dynamic font + break; + case 51: + // emacs shell + break; + case 52: + // manipulate selection data + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + // reset colors + break; + } + + this.params = []; + this.currentParam = 0; + this.state = ParserState.NORMAL; + } else { + if (!this.params.length) { + if (ch >= '0' && ch <= '9') { + this.currentParam = + this.currentParam * 10 + ch.charCodeAt(0) - 48; + } else if (ch === ';') { + this.params.push(this.currentParam); + this.currentParam = ''; + } + } else { + this.currentParam += ch; + } + } + break; + + case csi: + // '?', '>', '!' + if (ch === '?' || ch === '>' || ch === '!') { + this.prefix = ch; + break; + } + + // 0 - 9 + if (ch >= '0' && ch <= '9') { + this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; + break; + } + + // '$', '"', ' ', '\'' + if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { + this.postfix = ch; + break; + } + + this.params.push(this.currentParam); + this.currentParam = 0; + + // ';' + if (ch === ';') break; + + this.state = ParserState.NORMAL; + + switch (ch) { + // CSI Ps A + // Cursor Up Ps Times (default = 1) (CUU). + case 'A': + this.cursorUp(this.params); + break; + + // CSI Ps B + // Cursor Down Ps Times (default = 1) (CUD). + case 'B': + this.cursorDown(this.params); + break; + + // CSI Ps C + // Cursor Forward Ps Times (default = 1) (CUF). + case 'C': + this.cursorForward(this.params); + break; + + // CSI Ps D + // Cursor Backward Ps Times (default = 1) (CUB). + case 'D': + this.cursorBackward(this.params); + break; + + // CSI Ps ; Ps H + // Cursor Position [row;column] (default = [1,1]) (CUP). + case 'H': + this.cursorPos(this.params); + break; + + // CSI Ps J Erase in Display (ED). + case 'J': + this.eraseInDisplay(this.params); + break; + + // CSI Ps K Erase in Line (EL). + case 'K': + this.eraseInLine(this.params); + break; + + // CSI Pm m Character Attributes (SGR). + case 'm': + if (!this.prefix) { + this.charAttributes(this.params); + } + break; + + // CSI Ps n Device Status Report (DSR). + case 'n': + if (!this.prefix) { + this.deviceStatus(this.params); + } + break; + + /** + * Additions + */ + + // CSI Ps @ + // Insert Ps (Blank) Character(s) (default = 1) (ICH). + case '@': + this.insertChars(this.params); + break; + + // CSI Ps E + // Cursor Next Line Ps Times (default = 1) (CNL). + case 'E': + this.cursorNextLine(this.params); + break; + + // CSI Ps F + // Cursor Preceding Line Ps Times (default = 1) (CNL). + case 'F': + this.cursorPrecedingLine(this.params); + break; + + // CSI Ps G + // Cursor Character Absolute [column] (default = [row,1]) (CHA). + case 'G': + this.cursorCharAbsolute(this.params); + break; + + // CSI Ps L + // Insert Ps Line(s) (default = 1) (IL). + case 'L': + this.insertLines(this.params); + break; + + // CSI Ps M + // Delete Ps Line(s) (default = 1) (DL). + case 'M': + this.deleteLines(this.params); + break; + + // CSI Ps P + // Delete Ps Character(s) (default = 1) (DCH). + case 'P': + this.deleteChars(this.params); + break; + + // CSI Ps X + // Erase Ps Character(s) (default = 1) (ECH). + case 'X': + this.eraseChars(this.params); + break; + + // CSI Pm ` Character Position Absolute + // [column] (default = [row,1]) (HPA). + case '`': + this.charPosAbsolute(this.params); + break; + + // 141 61 a * HPR - + // Horizontal Position Relative + case 'a': + this.HPositionRelative(this.params); + break; + + // CSI P s c + // Send Device Attributes (Primary DA). + // CSI > P s c + // Send Device Attributes (Secondary DA) + case 'c': + this.sendDeviceAttributes(this.params); + break; + + // CSI Pm d + // Line Position Absolute [row] (default = [1,column]) (VPA). + case 'd': + this.linePosAbsolute(this.params); + break; + + // 145 65 e * VPR - Vertical Position Relative + case 'e': + this.VPositionRelative(this.params); + break; + + // CSI Ps ; Ps f + // Horizontal and Vertical Position [row;column] (default = + // [1,1]) (HVP). + case 'f': + this.HVPosition(this.params); + break; + + // CSI Pm h Set Mode (SM). + // CSI ? Pm h - mouse escape codes, cursor escape codes + case 'h': + this.setMode(this.params); + break; + + // CSI Pm l Reset Mode (RM). + // CSI ? Pm l + case 'l': + this.resetMode(this.params); + break; + + // CSI Ps ; Ps r + // Set Scrolling Region [top;bottom] (default = full size of win- + // dow) (DECSTBM). + // CSI ? Pm r + case 'r': + this.setScrollRegion(this.params); + break; + + // CSI s + // Save cursor (ANSI.SYS). + case 's': + this.saveCursor(this.params); + break; + + // CSI u + // Restore cursor (ANSI.SYS). + case 'u': + this.restoreCursor(this.params); + break; + + /** + * Lesser Used + */ + + // CSI Ps I + // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). + case 'I': + this.cursorForwardTab(this.params); + break; + + // CSI Ps S Scroll up Ps lines (default = 1) (SU). + case 'S': + this.scrollUp(this.params); + break; + + // CSI Ps T Scroll down Ps lines (default = 1) (SD). + // CSI Ps ; Ps ; Ps ; Ps ; Ps T + // CSI > Ps; Ps T + case 'T': + // if (this.prefix === '>') { + // this.resetTitleModes(this.params); + // break; + // } + // if (this.params.length > 2) { + // this.initMouseTracking(this.params); + // break; + // } + if (this.params.length < 2 && !this.prefix) { + this.scrollDown(this.params); + } + break; + + // CSI Ps Z + // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). + case 'Z': + this.cursorBackwardTab(this.params); + break; + + // CSI Ps b Repeat the preceding graphic character Ps times (REP). + case 'b': + this.repeatPrecedingCharacter(this.params); + break; + + // CSI Ps g Tab Clear (TBC). + case 'g': + this.tabClear(this.params); + break; + + // CSI Pm i Media Copy (MC). + // CSI ? Pm i + // case 'i': + // this.mediaCopy(this.params); + // break; + + // CSI Pm m Character Attributes (SGR). + // CSI > Ps; Ps m + // case 'm': // duplicate + // if (this.prefix === '>') { + // this.setResources(this.params); + // } else { + // this.charAttributes(this.params); + // } + // break; + + // CSI Ps n Device Status Report (DSR). + // CSI > Ps n + // case 'n': // duplicate + // if (this.prefix === '>') { + // this.disableModifiers(this.params); + // } else { + // this.deviceStatus(this.params); + // } + // break; + + // CSI > Ps p Set pointer mode. + // CSI ! p Soft terminal reset (DECSTR). + // CSI Ps$ p + // Request ANSI mode (DECRQM). + // CSI ? Ps$ p + // Request DEC private mode (DECRQM). + // CSI Ps ; Ps " p + case 'p': + switch (this.prefix) { + // case '>': + // this.setPointerMode(this.params); + // break; + case '!': + this.softReset(this.params); + break; + // case '?': + // if (this.postfix === '$') { + // this.requestPrivateMode(this.params); + // } + // break; + // default: + // if (this.postfix === '"') { + // this.setConformanceLevel(this.params); + // } else if (this.postfix === '$') { + // this.requestAnsiMode(this.params); + // } + // break; + } + break; + + // CSI Ps q Load LEDs (DECLL). + // CSI Ps SP q + // CSI Ps " q + // case 'q': + // if (this.postfix === ' ') { + // this.setCursorStyle(this.params); + // break; + // } + // if (this.postfix === '"') { + // this.setCharProtectionAttr(this.params); + // break; + // } + // this.loadLEDs(this.params); + // break; + + // CSI Ps ; Ps r + // Set Scrolling Region [top;bottom] (default = full size of win- + // dow) (DECSTBM). + // CSI ? Pm r + // CSI Pt; Pl; Pb; Pr; Ps$ r + // case 'r': // duplicate + // if (this.prefix === '?') { + // this.restorePrivateValues(this.params); + // } else if (this.postfix === '$') { + // this.setAttrInRectangle(this.params); + // } else { + // this.setScrollRegion(this.params); + // } + // break; + + // CSI s Save cursor (ANSI.SYS). + // CSI ? Pm s + // case 's': // duplicate + // if (this.prefix === '?') { + // this.savePrivateValues(this.params); + // } else { + // this.saveCursor(this.params); + // } + // break; + + // CSI Ps ; Ps ; Ps t + // CSI Pt; Pl; Pb; Pr; Ps$ t + // CSI > Ps; Ps t + // CSI Ps SP t + // case 't': + // if (this.postfix === '$') { + // this.reverseAttrInRectangle(this.params); + // } else if (this.postfix === ' ') { + // this.setWarningBellVolume(this.params); + // } else { + // if (this.prefix === '>') { + // this.setTitleModeFeature(this.params); + // } else { + // this.manipulateWindow(this.params); + // } + // } + // break; + + // CSI u Restore cursor (ANSI.SYS). + // CSI Ps SP u + // case 'u': // duplicate + // if (this.postfix === ' ') { + // this.setMarginBellVolume(this.params); + // } else { + // this.restoreCursor(this.params); + // } + // break; + + // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v + // case 'v': + // if (this.postfix === '$') { + // this.copyRectagle(this.params); + // } + // break; + + // CSI Pt ; Pl ; Pb ; Pr ' w + // case 'w': + // if (this.postfix === '\'') { + // this.enableFilterRectangle(this.params); + // } + // break; + + // CSI Ps x Request Terminal Parameters (DECREQTPARM). + // CSI Ps x Select Attribute Change Extent (DECSACE). + // CSI Pc; Pt; Pl; Pb; Pr$ x + // case 'x': + // if (this.postfix === '$') { + // this.fillRectangle(this.params); + // } else { + // this.requestParameters(this.params); + // //this.__(this.params); + // } + // break; + + // CSI Ps ; Pu ' z + // CSI Pt; Pl; Pb; Pr$ z + // case 'z': + // if (this.postfix === '\'') { + // this.enableLocatorReporting(this.params); + // } else if (this.postfix === '$') { + // this.eraseRectangle(this.params); + // } + // break; + + // CSI Pm ' { + // CSI Pt; Pl; Pb; Pr$ { + // case '{': + // if (this.postfix === '\'') { + // this.setLocatorEvents(this.params); + // } else if (this.postfix === '$') { + // this.selectiveEraseRectangle(this.params); + // } + // break; + + // CSI Ps ' | + // case '|': + // if (this.postfix === '\'') { + // this.requestLocatorPosition(this.params); + // } + // break; + + // CSI P m SP } + // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. + // case '}': + // if (this.postfix === ' ') { + // this.insertColumns(this.params); + // } + // break; + + // CSI P m SP ~ + // Delete P s Column(s) (default = 1) (DECDC), VT420 and up + // case '~': + // if (this.postfix === ' ') { + // this.deleteColumns(this.params); + // } + // break; + + default: + this.error('Unknown CSI code: %s.', ch); + break; + } + + this.prefix = ''; + this.postfix = ''; + break; + + case ParserState.DCS: + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) i++; + + switch (this.prefix) { + // User-Defined Keys (DECUDK). + case '': + break; + + // Request Status String (DECRQSS). + // test: echo -e '\eP$q"p\e\\' + case '$q': + var pt = this.currentParam + , valid = false; + + switch (pt) { + // DECSCA + case '"q': + pt = '0"q'; + break; + + // DECSCL + case '"p': + pt = '61"p'; + break; + + // DECSTBM + case 'r': + pt = '' + + (this.scrollTop + 1) + + ';' + + (this.scrollBottom + 1) + + 'r'; + break; + + // SGR + case 'm': + pt = '0m'; + break; + + default: + this.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + + this.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\'); + break; + + // Set Termcap/Terminfo Data (xterm, experimental). + case '+p': + break; + + // Request Termcap/Terminfo String (xterm, experimental) + // Regular xterm does not even respond to this sequence. + // This can cause a small glitch in vim. + // test: echo -ne '\eP+q6b64\e\\' + case '+q': + var pt = this.currentParam + , valid = false; + + this.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\'); + break; + + default: + this.error('Unknown DCS prefix: %s.', this.prefix); + break; + } + + this.currentParam = 0; + this.prefix = ''; + this.state = ParserState.NORMAL; + } else if (!this.currentParam) { + if (!this.prefix && ch !== '$' && ch !== '+') { + this.currentParam = ch; + } else if (this.prefix.length === 2) { + this.currentParam = ch; + } else { + this.prefix += ch; + } + } else { + this.currentParam += ch; + } + break; + + case ParserState.IGNORE: + // For PM and APC. + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) i++; + this.state = ParserState.NORMAL; + } + break; + } + } + } +} diff --git a/src/xterm.js b/src/xterm.js index 7d70c268..42661236 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -17,7 +17,7 @@ import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboa import { CircularList } from './utils/CircularList.js'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; -import * as parser from './Parser'; +import { Parser } from './Parser'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -206,6 +206,7 @@ function Terminal(options) { this.postfix = ''; this.inputHandler = new InputHandler(this); + this.parser = new Parser(this.inputHandler, this); // leftover surrogate high from previous write invocation this.surrogate_high = ''; @@ -1346,1005 +1347,10 @@ Terminal.prototype.scrollToBottom = function() { * @param {string} text The text to write to the terminal. */ Terminal.prototype.write = function(data) { - var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; - this.refreshStart = this.y; this.refreshEnd = this.y; - // apply leftover surrogate high from last write - if (this.surrogate_high) { - data = this.surrogate_high + data; - this.surrogate_high = ''; - } - - for (; i < l; i++) { - ch = data[i]; - - // FIXME: higher chars than 0xa0 are not allowed in escape sequences - // --> maybe move to default - code = data.charCodeAt(i); - if (0xD800 <= code && code <= 0xDBFF) { - // we got a surrogate high - // get surrogate low (next 2 bytes) - low = data.charCodeAt(i+1); - if (isNaN(low)) { - // end of data stream, save surrogate high - this.surrogate_high = ch; - continue; - } - code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; - ch += data.charAt(i+1); - } - // surrogate low - already handled above - if (0xDC00 <= code && code <= 0xDFFF) - continue; - - if (this.state === normal) { - if (ch in parser.normalStateHandler) { - parser.normalStateHandler[ch](this.inputHandler); - // Skip switch statement (eventually everything will be handled this way - continue; - } - } - - switch (this.state) { - case normal: - switch (ch) { - case C0.ESC: - this.state = escaped; - break; - - default: - // ' ' - // calculate print space - // expensive call, therefore we save width in line buffer - ch_width = wcwidth(code); - - if (ch >= ' ') { - if (this.charset && this.charset[ch]) { - ch = this.charset[ch]; - } - - row = this.y + this.ybase; - - // insert combining char in last cell - // FIXME: needs handling after cursor jumps - if (!ch_width && this.x) { - // dont overflow left - if (this.lines.get(row)[this.x-1]) { - if (!this.lines.get(row)[this.x-1][2]) { - - // found empty cell after fullwidth, need to go 2 cells back - if (this.lines.get(row)[this.x-2]) - this.lines.get(row)[this.x-2][1] += ch; - - } else { - this.lines.get(row)[this.x-1][1] += ch; - } - this.updateRange(this.y); - } - break; - } - - // goto next line if ch would overflow - // TODO: needs a global min terminal width of 2 - if (this.x+ch_width-1 >= this.cols) { - // autowrap - DECAWM - if (this.wraparoundMode) { - this.x = 0; - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); - } - } else { - this.x = this.cols-1; - if(ch_width===2) // FIXME: check for xterm behavior - continue; - } - } - row = this.y + this.ybase; - - // insert mode: move characters to right - if (this.insertMode) { - // do this twice for a fullwidth char - for (var moves=0; moves Normal Keypad (DECKPNM). - case '>': - this.log('Switching back to normal keypad.'); - this.applicationKeypad = false; - this.viewport.syncScrollArea(); - this.state = normal; - break; - - default: - this.state = normal; - this.error('Unknown ESC control: %s.', ch); - break; - } - break; - - case charset: - switch (ch) { - case '0': // DEC Special Character and Line Drawing Set. - cs = Terminal.charsets.SCLD; - break; - case 'A': // UK - cs = Terminal.charsets.UK; - break; - case 'B': // United States (USASCII). - cs = Terminal.charsets.US; - break; - case '4': // Dutch - cs = Terminal.charsets.Dutch; - break; - case 'C': // Finnish - case '5': - cs = Terminal.charsets.Finnish; - break; - case 'R': // French - cs = Terminal.charsets.French; - break; - case 'Q': // FrenchCanadian - cs = Terminal.charsets.FrenchCanadian; - break; - case 'K': // German - cs = Terminal.charsets.German; - break; - case 'Y': // Italian - cs = Terminal.charsets.Italian; - break; - case 'E': // NorwegianDanish - case '6': - cs = Terminal.charsets.NorwegianDanish; - break; - case 'Z': // Spanish - cs = Terminal.charsets.Spanish; - break; - case 'H': // Swedish - case '7': - cs = Terminal.charsets.Swedish; - break; - case '=': // Swiss - cs = Terminal.charsets.Swiss; - break; - case '/': // ISOLatin (actually /A) - cs = Terminal.charsets.ISOLatin; - i++; - break; - default: // Default - cs = Terminal.charsets.US; - break; - } - this.setgCharset(this.gcharset, cs); - this.gcharset = null; - this.state = normal; - break; - - case osc: - // OSC Ps ; Pt ST - // OSC Ps ; Pt BEL - // Set Text Parameters. - if (ch === C0.ESC || ch === C0.BEL) { - if (ch === C0.ESC) i++; - - this.params.push(this.currentParam); - - switch (this.params[0]) { - case 0: - case 1: - case 2: - if (this.params[1]) { - this.title = this.params[1]; - this.handleTitle(this.title); - } - break; - case 3: - // set X property - break; - case 4: - case 5: - // change dynamic colors - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - // change dynamic ui colors - break; - case 46: - // change log file - break; - case 50: - // dynamic font - break; - case 51: - // emacs shell - break; - case 52: - // manipulate selection data - break; - case 104: - case 105: - case 110: - case 111: - case 112: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: - // reset colors - break; - } - - this.params = []; - this.currentParam = 0; - this.state = normal; - } else { - if (!this.params.length) { - if (ch >= '0' && ch <= '9') { - this.currentParam = - this.currentParam * 10 + ch.charCodeAt(0) - 48; - } else if (ch === ';') { - this.params.push(this.currentParam); - this.currentParam = ''; - } - } else { - this.currentParam += ch; - } - } - break; - - case csi: - // '?', '>', '!' - if (ch === '?' || ch === '>' || ch === '!') { - this.prefix = ch; - break; - } - - // 0 - 9 - if (ch >= '0' && ch <= '9') { - this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; - break; - } - - // '$', '"', ' ', '\'' - if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { - this.postfix = ch; - break; - } - - this.params.push(this.currentParam); - this.currentParam = 0; - - // ';' - if (ch === ';') break; - - this.state = normal; - - switch (ch) { - // CSI Ps A - // Cursor Up Ps Times (default = 1) (CUU). - case 'A': - this.cursorUp(this.params); - break; - - // CSI Ps B - // Cursor Down Ps Times (default = 1) (CUD). - case 'B': - this.cursorDown(this.params); - break; - - // CSI Ps C - // Cursor Forward Ps Times (default = 1) (CUF). - case 'C': - this.cursorForward(this.params); - break; - - // CSI Ps D - // Cursor Backward Ps Times (default = 1) (CUB). - case 'D': - this.cursorBackward(this.params); - break; - - // CSI Ps ; Ps H - // Cursor Position [row;column] (default = [1,1]) (CUP). - case 'H': - this.cursorPos(this.params); - break; - - // CSI Ps J Erase in Display (ED). - case 'J': - this.eraseInDisplay(this.params); - break; - - // CSI Ps K Erase in Line (EL). - case 'K': - this.eraseInLine(this.params); - break; - - // CSI Pm m Character Attributes (SGR). - case 'm': - if (!this.prefix) { - this.charAttributes(this.params); - } - break; - - // CSI Ps n Device Status Report (DSR). - case 'n': - if (!this.prefix) { - this.deviceStatus(this.params); - } - break; - - /** - * Additions - */ - - // CSI Ps @ - // Insert Ps (Blank) Character(s) (default = 1) (ICH). - case '@': - this.insertChars(this.params); - break; - - // CSI Ps E - // Cursor Next Line Ps Times (default = 1) (CNL). - case 'E': - this.cursorNextLine(this.params); - break; - - // CSI Ps F - // Cursor Preceding Line Ps Times (default = 1) (CNL). - case 'F': - this.cursorPrecedingLine(this.params); - break; - - // CSI Ps G - // Cursor Character Absolute [column] (default = [row,1]) (CHA). - case 'G': - this.cursorCharAbsolute(this.params); - break; - - // CSI Ps L - // Insert Ps Line(s) (default = 1) (IL). - case 'L': - this.insertLines(this.params); - break; - - // CSI Ps M - // Delete Ps Line(s) (default = 1) (DL). - case 'M': - this.deleteLines(this.params); - break; - - // CSI Ps P - // Delete Ps Character(s) (default = 1) (DCH). - case 'P': - this.deleteChars(this.params); - break; - - // CSI Ps X - // Erase Ps Character(s) (default = 1) (ECH). - case 'X': - this.eraseChars(this.params); - break; - - // CSI Pm ` Character Position Absolute - // [column] (default = [row,1]) (HPA). - case '`': - this.charPosAbsolute(this.params); - break; - - // 141 61 a * HPR - - // Horizontal Position Relative - case 'a': - this.HPositionRelative(this.params); - break; - - // CSI P s c - // Send Device Attributes (Primary DA). - // CSI > P s c - // Send Device Attributes (Secondary DA) - case 'c': - this.sendDeviceAttributes(this.params); - break; - - // CSI Pm d - // Line Position Absolute [row] (default = [1,column]) (VPA). - case 'd': - this.linePosAbsolute(this.params); - break; - - // 145 65 e * VPR - Vertical Position Relative - case 'e': - this.VPositionRelative(this.params); - break; - - // CSI Ps ; Ps f - // Horizontal and Vertical Position [row;column] (default = - // [1,1]) (HVP). - case 'f': - this.HVPosition(this.params); - break; - - // CSI Pm h Set Mode (SM). - // CSI ? Pm h - mouse escape codes, cursor escape codes - case 'h': - this.setMode(this.params); - break; - - // CSI Pm l Reset Mode (RM). - // CSI ? Pm l - case 'l': - this.resetMode(this.params); - break; - - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - case 'r': - this.setScrollRegion(this.params); - break; - - // CSI s - // Save cursor (ANSI.SYS). - case 's': - this.saveCursor(this.params); - break; - - // CSI u - // Restore cursor (ANSI.SYS). - case 'u': - this.restoreCursor(this.params); - break; - - /** - * Lesser Used - */ - - // CSI Ps I - // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). - case 'I': - this.cursorForwardTab(this.params); - break; - - // CSI Ps S Scroll up Ps lines (default = 1) (SU). - case 'S': - this.scrollUp(this.params); - break; - - // CSI Ps T Scroll down Ps lines (default = 1) (SD). - // CSI Ps ; Ps ; Ps ; Ps ; Ps T - // CSI > Ps; Ps T - case 'T': - // if (this.prefix === '>') { - // this.resetTitleModes(this.params); - // break; - // } - // if (this.params.length > 2) { - // this.initMouseTracking(this.params); - // break; - // } - if (this.params.length < 2 && !this.prefix) { - this.scrollDown(this.params); - } - break; - - // CSI Ps Z - // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). - case 'Z': - this.cursorBackwardTab(this.params); - break; - - // CSI Ps b Repeat the preceding graphic character Ps times (REP). - case 'b': - this.repeatPrecedingCharacter(this.params); - break; - - // CSI Ps g Tab Clear (TBC). - case 'g': - this.tabClear(this.params); - break; - - // CSI Pm i Media Copy (MC). - // CSI ? Pm i - // case 'i': - // this.mediaCopy(this.params); - // break; - - // CSI Pm m Character Attributes (SGR). - // CSI > Ps; Ps m - // case 'm': // duplicate - // if (this.prefix === '>') { - // this.setResources(this.params); - // } else { - // this.charAttributes(this.params); - // } - // break; - - // CSI Ps n Device Status Report (DSR). - // CSI > Ps n - // case 'n': // duplicate - // if (this.prefix === '>') { - // this.disableModifiers(this.params); - // } else { - // this.deviceStatus(this.params); - // } - // break; - - // CSI > Ps p Set pointer mode. - // CSI ! p Soft terminal reset (DECSTR). - // CSI Ps$ p - // Request ANSI mode (DECRQM). - // CSI ? Ps$ p - // Request DEC private mode (DECRQM). - // CSI Ps ; Ps " p - case 'p': - switch (this.prefix) { - // case '>': - // this.setPointerMode(this.params); - // break; - case '!': - this.softReset(this.params); - break; - // case '?': - // if (this.postfix === '$') { - // this.requestPrivateMode(this.params); - // } - // break; - // default: - // if (this.postfix === '"') { - // this.setConformanceLevel(this.params); - // } else if (this.postfix === '$') { - // this.requestAnsiMode(this.params); - // } - // break; - } - break; - - // CSI Ps q Load LEDs (DECLL). - // CSI Ps SP q - // CSI Ps " q - // case 'q': - // if (this.postfix === ' ') { - // this.setCursorStyle(this.params); - // break; - // } - // if (this.postfix === '"') { - // this.setCharProtectionAttr(this.params); - // break; - // } - // this.loadLEDs(this.params); - // break; - - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - // CSI Pt; Pl; Pb; Pr; Ps$ r - // case 'r': // duplicate - // if (this.prefix === '?') { - // this.restorePrivateValues(this.params); - // } else if (this.postfix === '$') { - // this.setAttrInRectangle(this.params); - // } else { - // this.setScrollRegion(this.params); - // } - // break; - - // CSI s Save cursor (ANSI.SYS). - // CSI ? Pm s - // case 's': // duplicate - // if (this.prefix === '?') { - // this.savePrivateValues(this.params); - // } else { - // this.saveCursor(this.params); - // } - // break; - - // CSI Ps ; Ps ; Ps t - // CSI Pt; Pl; Pb; Pr; Ps$ t - // CSI > Ps; Ps t - // CSI Ps SP t - // case 't': - // if (this.postfix === '$') { - // this.reverseAttrInRectangle(this.params); - // } else if (this.postfix === ' ') { - // this.setWarningBellVolume(this.params); - // } else { - // if (this.prefix === '>') { - // this.setTitleModeFeature(this.params); - // } else { - // this.manipulateWindow(this.params); - // } - // } - // break; - - // CSI u Restore cursor (ANSI.SYS). - // CSI Ps SP u - // case 'u': // duplicate - // if (this.postfix === ' ') { - // this.setMarginBellVolume(this.params); - // } else { - // this.restoreCursor(this.params); - // } - // break; - - // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v - // case 'v': - // if (this.postfix === '$') { - // this.copyRectagle(this.params); - // } - // break; - - // CSI Pt ; Pl ; Pb ; Pr ' w - // case 'w': - // if (this.postfix === '\'') { - // this.enableFilterRectangle(this.params); - // } - // break; - - // CSI Ps x Request Terminal Parameters (DECREQTPARM). - // CSI Ps x Select Attribute Change Extent (DECSACE). - // CSI Pc; Pt; Pl; Pb; Pr$ x - // case 'x': - // if (this.postfix === '$') { - // this.fillRectangle(this.params); - // } else { - // this.requestParameters(this.params); - // //this.__(this.params); - // } - // break; - - // CSI Ps ; Pu ' z - // CSI Pt; Pl; Pb; Pr$ z - // case 'z': - // if (this.postfix === '\'') { - // this.enableLocatorReporting(this.params); - // } else if (this.postfix === '$') { - // this.eraseRectangle(this.params); - // } - // break; - - // CSI Pm ' { - // CSI Pt; Pl; Pb; Pr$ { - // case '{': - // if (this.postfix === '\'') { - // this.setLocatorEvents(this.params); - // } else if (this.postfix === '$') { - // this.selectiveEraseRectangle(this.params); - // } - // break; - - // CSI Ps ' | - // case '|': - // if (this.postfix === '\'') { - // this.requestLocatorPosition(this.params); - // } - // break; - - // CSI P m SP } - // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. - // case '}': - // if (this.postfix === ' ') { - // this.insertColumns(this.params); - // } - // break; - - // CSI P m SP ~ - // Delete P s Column(s) (default = 1) (DECDC), VT420 and up - // case '~': - // if (this.postfix === ' ') { - // this.deleteColumns(this.params); - // } - // break; - - default: - this.error('Unknown CSI code: %s.', ch); - break; - } - - this.prefix = ''; - this.postfix = ''; - break; - - case dcs: - if (ch === C0.ESC || ch === C0.BEL) { - if (ch === C0.ESC) i++; - - switch (this.prefix) { - // User-Defined Keys (DECUDK). - case '': - break; - - // Request Status String (DECRQSS). - // test: echo -e '\eP$q"p\e\\' - case '$q': - var pt = this.currentParam - , valid = false; - - switch (pt) { - // DECSCA - case '"q': - pt = '0"q'; - break; - - // DECSCL - case '"p': - pt = '61"p'; - break; - - // DECSTBM - case 'r': - pt = '' - + (this.scrollTop + 1) - + ';' - + (this.scrollBottom + 1) - + 'r'; - break; - - // SGR - case 'm': - pt = '0m'; - break; - - default: - this.error('Unknown DCS Pt: %s.', pt); - pt = ''; - break; - } - - this.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\'); - break; - - // Set Termcap/Terminfo Data (xterm, experimental). - case '+p': - break; - - // Request Termcap/Terminfo String (xterm, experimental) - // Regular xterm does not even respond to this sequence. - // This can cause a small glitch in vim. - // test: echo -ne '\eP+q6b64\e\\' - case '+q': - var pt = this.currentParam - , valid = false; - - this.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\'); - break; - - default: - this.error('Unknown DCS prefix: %s.', this.prefix); - break; - } - - this.currentParam = 0; - this.prefix = ''; - this.state = normal; - } else if (!this.currentParam) { - if (!this.prefix && ch !== '$' && ch !== '+') { - this.currentParam = ch; - } else if (this.prefix.length === 2) { - this.currentParam = ch; - } else { - this.prefix += ch; - } - } else { - this.currentParam += ch; - } - break; - - case ignore: - // For PM and APC. - if (ch === C0.ESC || ch === C0.BEL) { - if (ch === C0.ESC) i++; - this.state = normal; - } - break; - } - } + this.parser.parse(data); this.updateRange(this.y); this.refresh(this.refreshStart, this.refreshEnd); @@ -4996,109 +4002,6 @@ function keys(obj) { return keys; } -var wcwidth = (function(opts) { - // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c - // combining characters - var COMBINING = [ - [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], - [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], - [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], - [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], - [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], - [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], - [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], - [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], - [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], - [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], - [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], - [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], - [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], - [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], - [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], - [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], - [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], - [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], - [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], - [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], - [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], - [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], - [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], - [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], - [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], - [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], - [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], - [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], - [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], - [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], - [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], - [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], - [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], - [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], - [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], - [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], - [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], - [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], - [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], - [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], - [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], - [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], - [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], - [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], - [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], - [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], - [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], - [0xE0100, 0xE01EF] - ]; - // binary search - function bisearch(ucs) { - var min = 0; - var max = COMBINING.length - 1; - var mid; - if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1]) - return false; - while (max >= min) { - mid = Math.floor((min + max) / 2); - if (ucs > COMBINING[mid][1]) - min = mid + 1; - else if (ucs < COMBINING[mid][0]) - max = mid - 1; - else - return true; - } - return false; - } - function wcwidth(ucs) { - // test for 8-bit control characters - if (ucs === 0) - return opts.nul; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return opts.control; - // binary search in table of non-spacing characters - if (bisearch(ucs)) - return 0; - // if we arrive here, ucs is not a combining or C0/C1 control character - return 1 + - ( - ucs >= 0x1100 && - ( - ucs <= 0x115f || // Hangul Jamo init. consonants - ucs == 0x2329 || - ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || // CJK..Yi - (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables - (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs - (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms - (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms - (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd) - ) - ); - } - return wcwidth; -})({nul: 0, control: 0}); // configurable options - /** * Expose */ From 4a27b9a53f9921039a4a1e05585854adf19ae857 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 13:46:08 -0800 Subject: [PATCH 019/211] Move wcwidth into Parser.ts --- src/Parser.ts | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/src/Parser.ts b/src/Parser.ts index 517103d2..94f48149 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1032,3 +1032,106 @@ export class Parser { } } } + +var wcwidth = (function(opts) { + // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c + // combining characters + var COMBINING = [ + [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], + [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], + [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], + [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], + [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], + [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], + [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], + [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], + [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], + [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], + [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], + [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], + [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], + [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], + [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], + [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], + [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], + [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], + [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], + [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], + [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], + [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], + [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], + [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], + [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], + [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], + [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], + [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], + [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], + [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], + [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], + [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], + [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], + [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], + [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], + [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], + [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], + [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], + [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], + [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], + [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], + [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], + [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], + [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], + [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], + [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], + [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], + [0xE0100, 0xE01EF] + ]; + // binary search + function bisearch(ucs) { + var min = 0; + var max = COMBINING.length - 1; + var mid; + if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1]) + return false; + while (max >= min) { + mid = Math.floor((min + max) / 2); + if (ucs > COMBINING[mid][1]) + min = mid + 1; + else if (ucs < COMBINING[mid][0]) + max = mid - 1; + else + return true; + } + return false; + } + function wcwidth(ucs) { + // test for 8-bit control characters + if (ucs === 0) + return opts.nul; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return opts.control; + // binary search in table of non-spacing characters + if (bisearch(ucs)) + return 0; + // if we arrive here, ucs is not a combining or C0/C1 control character + return 1 + + ( + ucs >= 0x1100 && + ( + ucs <= 0x115f || // Hangul Jamo init. consonants + ucs == 0x2329 || + ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || // CJK..Yi + (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables + (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs + (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms + (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms + (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd) + ) + ); + } + return wcwidth; +})({nul: 0, control: 0}); // configurable options From 940bd2699e6a9cb9ac4d7eaecb3ccf698ca09422 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 13:48:36 -0800 Subject: [PATCH 020/211] Fix wcwidth TS errors --- src/Parser.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 94f48149..15719640 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1033,10 +1033,10 @@ export class Parser { } } -var wcwidth = (function(opts) { +const wcwidth = (function(opts) { // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c // combining characters - var COMBINING = [ + const COMBINING = [ [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], @@ -1088,9 +1088,9 @@ var wcwidth = (function(opts) { ]; // binary search function bisearch(ucs) { - var min = 0; - var max = COMBINING.length - 1; - var mid; + let min = 0; + let max = COMBINING.length - 1; + let mid; if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1]) return false; while (max >= min) { @@ -1114,14 +1114,18 @@ var wcwidth = (function(opts) { if (bisearch(ucs)) return 0; // if we arrive here, ucs is not a combining or C0/C1 control character - return 1 + - ( - ucs >= 0x1100 && - ( + if (isWide(ucs)) { + return 2; + } + return 1; + } + function isWide(ucs) { + return ( + ucs >= 0x1100 && ( ucs <= 0x115f || // Hangul Jamo init. consonants - ucs == 0x2329 || - ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || // CJK..Yi + ucs === 0x2329 || + ucs === 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms @@ -1129,9 +1133,7 @@ var wcwidth = (function(opts) { (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms (ucs >= 0xffe0 && ucs <= 0xffe6) || (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd) - ) - ); + (ucs >= 0x30000 && ucs <= 0x3fffd))); } return wcwidth; })({nul: 0, control: 0}); // configurable options From 991b2843d3c93c21d8e2a02a25fd0b57b1c051f3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 13:57:58 -0800 Subject: [PATCH 021/211] Fix references to Terminaal and fix TS lint warnings --- src/Parser.ts | 313 +++++++++++++++++++++++++------------------------- 1 file changed, 157 insertions(+), 156 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 15719640..b04327e1 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -51,14 +51,14 @@ export class Parser { if (0xD800 <= code && code <= 0xDBFF) { // we got a surrogate high // get surrogate low (next 2 bytes) - low = data.charCodeAt(i+1); + low = data.charCodeAt(i + 1); if (isNaN(low)) { // end of data stream, save surrogate high this._terminal.surrogate_high = ch; continue; } code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; - ch += data.charAt(i+1); + ch += data.charAt(i + 1); } // surrogate low - already handled above if (0xDC00 <= code && code <= 0xDFFF) @@ -86,75 +86,75 @@ export class Parser { ch_width = wcwidth(code); if (ch >= ' ') { - if (this.charset && this.charset[ch]) { - ch = this.charset[ch]; + if (this._terminal.charset && this._terminal.charset[ch]) { + ch = this._terminal.charset[ch]; } - row = this.y + this.ybase; + row = this._terminal.y + this._terminal.ybase; // insert combining char in last cell // FIXME: needs handling after cursor jumps - if (!ch_width && this.x) { + if (!ch_width && this._terminal.x) { // dont overflow left - if (this.lines.get(row)[this.x-1]) { - if (!this.lines.get(row)[this.x-1][2]) { + if (this._terminal.lines.get(row)[this._terminal.x - 1]) { + if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) { // found empty cell after fullwidth, need to go 2 cells back - if (this.lines.get(row)[this.x-2]) - this.lines.get(row)[this.x-2][1] += ch; + if (this._terminal.lines.get(row)[this._terminal.x - 2]) + this._terminal.lines.get(row)[this._terminal.x - 2][1] += ch; } else { - this.lines.get(row)[this.x-1][1] += ch; + this._terminal.lines.get(row)[this._terminal.x - 1][1] += ch; } - this.updateRange(this.y); + this._terminal.updateRange(this._terminal.y); } break; } // goto next line if ch would overflow // TODO: needs a global min terminal width of 2 - if (this.x+ch_width-1 >= this.cols) { + if (this._terminal.x + ch_width - 1 >= this._terminal.cols) { // autowrap - DECAWM - if (this.wraparoundMode) { - this.x = 0; - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); + if (this._terminal.wraparoundMode) { + this._terminal.x = 0; + this._terminal.y++; + if (this._terminal.y > this._terminal.scrollBottom) { + this._terminal.y--; + this._terminal.scroll(); } } else { - this.x = this.cols-1; - if(ch_width===2) // FIXME: check for xterm behavior + this._terminal.x = this._terminal.cols - 1; + if (ch_width === 2) // FIXME: check for xterm behavior continue; } } - row = this.y + this.ybase; + row = this._terminal.y + this._terminal.ybase; // insert mode: move characters to right - if (this.insertMode) { + if (this._terminal.insertMode) { // do this twice for a fullwidth char - for (var moves=0; moves Normal Keypad (DECKPNM). case '>': - this.log('Switching back to normal keypad.'); - this.applicationKeypad = false; - this.viewport.syncScrollArea(); + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); this.state = ParserState.NORMAL; break; default: this.state = ParserState.NORMAL; - this.error('Unknown ESC control: %s.', ch); + this._terminal.error('Unknown ESC control: %s.', ch); break; } break; @@ -395,8 +395,8 @@ export class Parser { cs = Terminal.charsets.US; break; } - this.setgCharset(this.gcharset, cs); - this.gcharset = null; + this._terminal.setgCharset(this._terminal.gcharset, cs); + this._terminal.gcharset = null; this.state = ParserState.NORMAL; break; @@ -407,15 +407,15 @@ export class Parser { if (ch === C0.ESC || ch === C0.BEL) { if (ch === C0.ESC) i++; - this.params.push(this.currentParam); + this._terminal.params.push(this._terminal.currentParam); - switch (this.params[0]) { + switch (this._terminal.params[0]) { case 0: case 1: case 2: - if (this.params[1]) { - this.title = this.params[1]; - this.handleTitle(this.title); + if (this._terminal.params[1]) { + this._terminal.title = this._terminal.params[1]; + this._terminal.handleTitle(this._terminal.title); } break; case 3: @@ -464,45 +464,45 @@ export class Parser { break; } - this.params = []; - this.currentParam = 0; + this._terminal.params = []; + this._terminal.currentParam = 0; this.state = ParserState.NORMAL; } else { - if (!this.params.length) { + if (!this._terminal.params.length) { if (ch >= '0' && ch <= '9') { - this.currentParam = - this.currentParam * 10 + ch.charCodeAt(0) - 48; + this._terminal.currentParam = + this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; } else if (ch === ';') { - this.params.push(this.currentParam); - this.currentParam = ''; + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = ''; } } else { - this.currentParam += ch; + this._terminal.currentParam += ch; } } break; - case csi: + case ParserState.CSI: // '?', '>', '!' if (ch === '?' || ch === '>' || ch === '!') { - this.prefix = ch; + this._terminal.prefix = ch; break; } // 0 - 9 if (ch >= '0' && ch <= '9') { - this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; + this._terminal.currentParam = this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; break; } // '$', '"', ' ', '\'' if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { - this.postfix = ch; + this._terminal.postfix = ch; break; } - this.params.push(this.currentParam); - this.currentParam = 0; + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = 0; // ';' if (ch === ';') break; @@ -513,54 +513,54 @@ export class Parser { // CSI Ps A // Cursor Up Ps Times (default = 1) (CUU). case 'A': - this.cursorUp(this.params); + this._terminal.cursorUp(this._terminal.params); break; // CSI Ps B // Cursor Down Ps Times (default = 1) (CUD). case 'B': - this.cursorDown(this.params); + this._terminal.cursorDown(this._terminal.params); break; // CSI Ps C // Cursor Forward Ps Times (default = 1) (CUF). case 'C': - this.cursorForward(this.params); + this._terminal.cursorForward(this._terminal.params); break; // CSI Ps D // Cursor Backward Ps Times (default = 1) (CUB). case 'D': - this.cursorBackward(this.params); + this._terminal.cursorBackward(this._terminal.params); break; // CSI Ps ; Ps H // Cursor Position [row;column] (default = [1,1]) (CUP). case 'H': - this.cursorPos(this.params); + this._terminal.cursorPos(this._terminal.params); break; // CSI Ps J Erase in Display (ED). case 'J': - this.eraseInDisplay(this.params); + this._terminal.eraseInDisplay(this._terminal.params); break; // CSI Ps K Erase in Line (EL). case 'K': - this.eraseInLine(this.params); + this._terminal.eraseInLine(this._terminal.params); break; // CSI Pm m Character Attributes (SGR). case 'm': - if (!this.prefix) { - this.charAttributes(this.params); + if (!this._terminal.prefix) { + this._terminal.charAttributes(this._terminal.params); } break; // CSI Ps n Device Status Report (DSR). case 'n': - if (!this.prefix) { - this.deviceStatus(this.params); + if (!this._terminal.prefix) { + this._terminal.deviceStatus(this._terminal.params); } break; @@ -571,61 +571,61 @@ export class Parser { // CSI Ps @ // Insert Ps (Blank) Character(s) (default = 1) (ICH). case '@': - this.insertChars(this.params); + this._terminal.insertChars(this._terminal.params); break; // CSI Ps E // Cursor Next Line Ps Times (default = 1) (CNL). case 'E': - this.cursorNextLine(this.params); + this._terminal.cursorNextLine(this._terminal.params); break; // CSI Ps F // Cursor Preceding Line Ps Times (default = 1) (CNL). case 'F': - this.cursorPrecedingLine(this.params); + this._terminal.cursorPrecedingLine(this._terminal.params); break; // CSI Ps G // Cursor Character Absolute [column] (default = [row,1]) (CHA). case 'G': - this.cursorCharAbsolute(this.params); + this._terminal.cursorCharAbsolute(this._terminal.params); break; // CSI Ps L // Insert Ps Line(s) (default = 1) (IL). case 'L': - this.insertLines(this.params); + this._terminal.insertLines(this._terminal.params); break; // CSI Ps M // Delete Ps Line(s) (default = 1) (DL). case 'M': - this.deleteLines(this.params); + this._terminal.deleteLines(this._terminal.params); break; // CSI Ps P // Delete Ps Character(s) (default = 1) (DCH). case 'P': - this.deleteChars(this.params); + this._terminal.deleteChars(this._terminal.params); break; // CSI Ps X // Erase Ps Character(s) (default = 1) (ECH). case 'X': - this.eraseChars(this.params); + this._terminal.eraseChars(this._terminal.params); break; // CSI Pm ` Character Position Absolute // [column] (default = [row,1]) (HPA). case '`': - this.charPosAbsolute(this.params); + this._terminal.charPosAbsolute(this._terminal.params); break; // 141 61 a * HPR - // Horizontal Position Relative case 'a': - this.HPositionRelative(this.params); + this._terminal.HPositionRelative(this._terminal.params); break; // CSI P s c @@ -633,37 +633,37 @@ export class Parser { // CSI > P s c // Send Device Attributes (Secondary DA) case 'c': - this.sendDeviceAttributes(this.params); + this._terminal.sendDeviceAttributes(this._terminal.params); break; // CSI Pm d // Line Position Absolute [row] (default = [1,column]) (VPA). case 'd': - this.linePosAbsolute(this.params); + this._terminal.linePosAbsolute(this._terminal.params); break; // 145 65 e * VPR - Vertical Position Relative case 'e': - this.VPositionRelative(this.params); + this._terminal.VPositionRelative(this._terminal.params); break; // CSI Ps ; Ps f // Horizontal and Vertical Position [row;column] (default = // [1,1]) (HVP). case 'f': - this.HVPosition(this.params); + this._terminal.HVPosition(this._terminal.params); break; // CSI Pm h Set Mode (SM). // CSI ? Pm h - mouse escape codes, cursor escape codes case 'h': - this.setMode(this.params); + this._terminal.setMode(this._terminal.params); break; // CSI Pm l Reset Mode (RM). // CSI ? Pm l case 'l': - this.resetMode(this.params); + this._terminal.resetMode(this._terminal.params); break; // CSI Ps ; Ps r @@ -671,19 +671,19 @@ export class Parser { // dow) (DECSTBM). // CSI ? Pm r case 'r': - this.setScrollRegion(this.params); + this._terminal.setScrollRegion(this._terminal.params); break; // CSI s // Save cursor (ANSI.SYS). case 's': - this.saveCursor(this.params); + this._terminal.saveCursor(this._terminal.params); break; // CSI u // Restore cursor (ANSI.SYS). case 'u': - this.restoreCursor(this.params); + this._terminal.restoreCursor(this._terminal.params); break; /** @@ -693,12 +693,12 @@ export class Parser { // CSI Ps I // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). case 'I': - this.cursorForwardTab(this.params); + this._terminal.cursorForwardTab(this._terminal.params); break; // CSI Ps S Scroll up Ps lines (default = 1) (SU). case 'S': - this.scrollUp(this.params); + this._terminal.scrollUp(this._terminal.params); break; // CSI Ps T Scroll down Ps lines (default = 1) (SD). @@ -713,25 +713,25 @@ export class Parser { // this.initMouseTracking(this.params); // break; // } - if (this.params.length < 2 && !this.prefix) { - this.scrollDown(this.params); + if (this._terminal.params.length < 2 && !this._terminal.prefix) { + this._terminal.scrollDown(this._terminal.params); } break; // CSI Ps Z // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). case 'Z': - this.cursorBackwardTab(this.params); + this._terminal.cursorBackwardTab(this._terminal.params); break; // CSI Ps b Repeat the preceding graphic character Ps times (REP). case 'b': - this.repeatPrecedingCharacter(this.params); + this._terminal.repeatPrecedingCharacter(this._terminal.params); break; // CSI Ps g Tab Clear (TBC). case 'g': - this.tabClear(this.params); + this._terminal.tabClear(this._terminal.params); break; // CSI Pm i Media Copy (MC). @@ -768,12 +768,12 @@ export class Parser { // Request DEC private mode (DECRQM). // CSI Ps ; Ps " p case 'p': - switch (this.prefix) { + switch (this._terminal.prefix) { // case '>': // this.setPointerMode(this.params); // break; case '!': - this.softReset(this.params); + this._terminal.softReset(this._terminal.params); break; // case '?': // if (this.postfix === '$') { @@ -928,19 +928,19 @@ export class Parser { // break; default: - this.error('Unknown CSI code: %s.', ch); + this._terminal.error('Unknown CSI code: %s.', ch); break; } - this.prefix = ''; - this.postfix = ''; + this._terminal.prefix = ''; + this._terminal.postfix = ''; break; case ParserState.DCS: if (ch === C0.ESC || ch === C0.BEL) { if (ch === C0.ESC) i++; - switch (this.prefix) { + switch (this._terminal.prefix) { // User-Defined Keys (DECUDK). case '': break; @@ -948,7 +948,7 @@ export class Parser { // Request Status String (DECRQSS). // test: echo -e '\eP$q"p\e\\' case '$q': - var pt = this.currentParam + let pt = this._terminal.currentParam , valid = false; switch (pt) { @@ -965,9 +965,9 @@ export class Parser { // DECSTBM case 'r': pt = '' - + (this.scrollTop + 1) + + (this._terminal.scrollTop + 1) + ';' - + (this.scrollBottom + 1) + + (this._terminal.scrollBottom + 1) + 'r'; break; @@ -977,12 +977,12 @@ export class Parser { break; default: - this.error('Unknown DCS Pt: %s.', pt); + this._terminal.error('Unknown DCS Pt: %s.', pt); pt = ''; break; } - this.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\'); + this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\'); break; // Set Termcap/Terminfo Data (xterm, experimental). @@ -994,30 +994,31 @@ export class Parser { // This can cause a small glitch in vim. // test: echo -ne '\eP+q6b64\e\\' case '+q': - var pt = this.currentParam + // TODO: Don't declare pt twice + /*let*/ pt = this._terminal.currentParam , valid = false; - this.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\'); + this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\'); break; default: - this.error('Unknown DCS prefix: %s.', this.prefix); + this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix); break; } - this.currentParam = 0; - this.prefix = ''; + this._terminal.currentParam = 0; + this._terminal.prefix = ''; this.state = ParserState.NORMAL; - } else if (!this.currentParam) { - if (!this.prefix && ch !== '$' && ch !== '+') { - this.currentParam = ch; - } else if (this.prefix.length === 2) { - this.currentParam = ch; + } else if (!this._terminal.currentParam) { + if (!this._terminal.prefix && ch !== '$' && ch !== '+') { + this._terminal.currentParam = ch; + } else if (this._terminal.prefix.length === 2) { + this._terminal.currentParam = ch; } else { - this.prefix += ch; + this._terminal.prefix += ch; } } else { - this.currentParam += ch; + this._terminal.currentParam += ch; } break; From 1848fff4c97f57310f2c90edd3e9825bbc4d0488 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 14:21:59 -0800 Subject: [PATCH 022/211] Pull charsets out of xterm.js --- src/Charsets.ts | 58 +++++++++++++++++++++++++++++++++++++++ src/Parser.ts | 33 +++++++++++----------- src/xterm.js | 73 ++++--------------------------------------------- 3 files changed, 81 insertions(+), 83 deletions(-) create mode 100644 src/Charsets.ts diff --git a/src/Charsets.ts b/src/Charsets.ts new file mode 100644 index 00000000..4035d453 --- /dev/null +++ b/src/Charsets.ts @@ -0,0 +1,58 @@ +// TODO: Give this a proper type +export const CHARSETS: any = {}; + +// DEC Special Character and Line Drawing Set. +// http://vt100.net/docs/vt102-ug/table5-13.html +// A lot of curses apps use this if they see TERM=xterm. +// testing: echo -e '\e(0a\e(B' +// The xterm output sometimes seems to conflict with the +// reference above. xterm seems in line with the reference +// when running vttest however. +// The table below now uses xterm's output from vttest. +CHARSETS.SCLD = { // (0 + '`': '\u25c6', // '◆' + 'a': '\u2592', // '▒' + 'b': '\u0009', // '\t' + 'c': '\u000c', // '\f' + 'd': '\u000d', // '\r' + 'e': '\u000a', // '\n' + 'f': '\u00b0', // '°' + 'g': '\u00b1', // '±' + 'h': '\u2424', // '\u2424' (NL) + 'i': '\u000b', // '\v' + 'j': '\u2518', // '┘' + 'k': '\u2510', // '┐' + 'l': '\u250c', // '┌' + 'm': '\u2514', // '└' + 'n': '\u253c', // '┼' + 'o': '\u23ba', // '⎺' + 'p': '\u23bb', // '⎻' + 'q': '\u2500', // '─' + 'r': '\u23bc', // '⎼' + 's': '\u23bd', // '⎽' + 't': '\u251c', // '├' + 'u': '\u2524', // '┤' + 'v': '\u2534', // '┴' + 'w': '\u252c', // '┬' + 'x': '\u2502', // '│' + 'y': '\u2264', // '≤' + 'z': '\u2265', // '≥' + '{': '\u03c0', // 'π' + '|': '\u2260', // '≠' + '}': '\u00a3', // '£' + '~': '\u00b7' // '·' +}; + +CHARSETS.UK = null; // (A +CHARSETS.US = null; // (B (USASCII) +CHARSETS.Dutch = null; // (4 +CHARSETS.Finnish = null; // (C or (5 +CHARSETS.French = null; // (R +CHARSETS.FrenchCanadian = null; // (Q +CHARSETS.German = null; // (K +CHARSETS.Italian = null; // (Y +CHARSETS.NorwegianDanish = null; // (E or (6 +CHARSETS.Spanish = null; // (Z +CHARSETS.Swedish = null; // (H or (7 +CHARSETS.Swiss = null; // (= +CHARSETS.ISOLatin = null; // /A diff --git a/src/Parser.ts b/src/Parser.ts index b04327e1..ef10abc5 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1,5 +1,6 @@ import { C0 } from './EscapeSequences'; import { IInputHandler } from './Interfaces'; +import { CHARSETS } from './Charsets'; const normalStateHandler: {[key: string]: (handler: IInputHandler) => void} = {}; normalStateHandler[C0.BEL] = (handler) => handler.bell(); @@ -217,7 +218,7 @@ export class Parser { case '%': // this.charset = null; this._terminal.setgLevel(0); - this._terminal.setgCharset(0, Terminal.charsets.US); + this._terminal.setgCharset(0, CHARSETS.US); this.state = ParserState.NORMAL; i++; break; @@ -346,53 +347,53 @@ export class Parser { case ParserState.CHARSET: switch (ch) { case '0': // DEC Special Character and Line Drawing Set. - cs = Terminal.charsets.SCLD; + cs = CHARSETS.SCLD; break; case 'A': // UK - cs = Terminal.charsets.UK; + cs = CHARSETS.UK; break; case 'B': // United States (USASCII). - cs = Terminal.charsets.US; + cs = CHARSETS.US; break; case '4': // Dutch - cs = Terminal.charsets.Dutch; + cs = CHARSETS.Dutch; break; case 'C': // Finnish case '5': - cs = Terminal.charsets.Finnish; + cs = CHARSETS.Finnish; break; case 'R': // French - cs = Terminal.charsets.French; + cs = CHARSETS.French; break; case 'Q': // FrenchCanadian - cs = Terminal.charsets.FrenchCanadian; + cs = CHARSETS.FrenchCanadian; break; case 'K': // German - cs = Terminal.charsets.German; + cs = CHARSETS.German; break; case 'Y': // Italian - cs = Terminal.charsets.Italian; + cs = CHARSETS.Italian; break; case 'E': // NorwegianDanish case '6': - cs = Terminal.charsets.NorwegianDanish; + cs = CHARSETS.NorwegianDanish; break; case 'Z': // Spanish - cs = Terminal.charsets.Spanish; + cs = CHARSETS.Spanish; break; case 'H': // Swedish case '7': - cs = Terminal.charsets.Swedish; + cs = CHARSETS.Swedish; break; case '=': // Swiss - cs = Terminal.charsets.Swiss; + cs = CHARSETS.Swiss; break; case '/': // ISOLatin (actually /A) - cs = Terminal.charsets.ISOLatin; + cs = CHARSETS.ISOLatin; i++; break; default: // Default - cs = Terminal.charsets.US; + cs = CHARSETS.US; break; } this._terminal.setgCharset(this._terminal.gcharset, cs); diff --git a/src/xterm.js b/src/xterm.js index 42661236..5f43c381 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -17,9 +17,10 @@ import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboa import { CircularList } from './utils/CircularList.js'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; -import { Parser } from './Parser'; +import { Parser } from './Parser'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; +import { CHARSETS } from './Charsets'; /** * Terminal Emulation References: @@ -3030,10 +3031,10 @@ Terminal.prototype.setMode = function(params) { this.applicationCursor = true; break; case 2: - this.setgCharset(0, Terminal.charsets.US); - this.setgCharset(1, Terminal.charsets.US); - this.setgCharset(2, Terminal.charsets.US); - this.setgCharset(3, Terminal.charsets.US); + this.setgCharset(0, CHARSETS.US); + this.setgCharset(1, CHARSETS.US); + this.setgCharset(2, CHARSETS.US); + this.setgCharset(3, CHARSETS.US); // set VT100 mode here break; case 3: // 132 col mode @@ -3806,68 +3807,6 @@ Terminal.prototype.deleteColumns = function() { this.maxRange(); }; -/** - * Character Sets - */ - -Terminal.charsets = {}; - -// DEC Special Character and Line Drawing Set. -// http://vt100.net/docs/vt102-ug/table5-13.html -// A lot of curses apps use this if they see TERM=xterm. -// testing: echo -e '\e(0a\e(B' -// The xterm output sometimes seems to conflict with the -// reference above. xterm seems in line with the reference -// when running vttest however. -// The table below now uses xterm's output from vttest. -Terminal.charsets.SCLD = { // (0 - '`': '\u25c6', // '◆' - 'a': '\u2592', // '▒' - 'b': '\u0009', // '\t' - 'c': '\u000c', // '\f' - 'd': '\u000d', // '\r' - 'e': '\u000a', // '\n' - 'f': '\u00b0', // '°' - 'g': '\u00b1', // '±' - 'h': '\u2424', // '\u2424' (NL) - 'i': '\u000b', // '\v' - 'j': '\u2518', // '┘' - 'k': '\u2510', // '┐' - 'l': '\u250c', // '┌' - 'm': '\u2514', // '└' - 'n': '\u253c', // '┼' - 'o': '\u23ba', // '⎺' - 'p': '\u23bb', // '⎻' - 'q': '\u2500', // '─' - 'r': '\u23bc', // '⎼' - 's': '\u23bd', // '⎽' - 't': '\u251c', // '├' - 'u': '\u2524', // '┤' - 'v': '\u2534', // '┴' - 'w': '\u252c', // '┬' - 'x': '\u2502', // '│' - 'y': '\u2264', // '≤' - 'z': '\u2265', // '≥' - '{': '\u03c0', // 'π' - '|': '\u2260', // '≠' - '}': '\u00a3', // '£' - '~': '\u00b7' // '·' -}; - -Terminal.charsets.UK = null; // (A -Terminal.charsets.US = null; // (B (USASCII) -Terminal.charsets.Dutch = null; // (4 -Terminal.charsets.Finnish = null; // (C or (5 -Terminal.charsets.French = null; // (R -Terminal.charsets.FrenchCanadian = null; // (Q -Terminal.charsets.German = null; // (K -Terminal.charsets.Italian = null; // (Y -Terminal.charsets.NorwegianDanish = null; // (E or (6 -Terminal.charsets.Spanish = null; // (Z -Terminal.charsets.Swedish = null; // (H or (7 -Terminal.charsets.Swiss = null; // (= -Terminal.charsets.ISOLatin = null; // /A - /** * Helpers */ From 6deaaa8ef8e87a9993a6c4737eb88b7dcc8593e4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 15:00:37 -0800 Subject: [PATCH 023/211] Move all parser state handling into the parser --- src/Parser.ts | 3 +++ src/xterm.js | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index ef10abc5..42d429a3 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -206,11 +206,13 @@ export class Parser { ; case 'D': this._terminal.index(); + this.state = ParserState.NORMAL; break; // ESC M Reverse Index ( RI is 0x8d). case 'M': this._terminal.reverseIndex(); + this.state = ParserState.NORMAL; break; // ESC % Select default/utf-8 character set. @@ -319,6 +321,7 @@ export class Parser { // ESC H Tab Set (HTS is 0x88). case 'H': this._terminal.tabSet(); + this.state = ParserState.NORMAL; break; // ESC = Application Keypad (DECKPAM). diff --git a/src/xterm.js b/src/xterm.js index a100f802..bf9f9853 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -148,7 +148,6 @@ function Terminal(options) { this.cursorState = 0; this.cursorHidden = false; this.convertEol; - this.state = 0; this.queue = ''; this.scrollTop = 0; this.scrollBottom = this.rows - 1; @@ -2173,7 +2172,6 @@ Terminal.prototype.index = function() { this.y--; this.scroll(); } - this.state = normal; }; @@ -2195,7 +2193,6 @@ Terminal.prototype.reverseIndex = function() { } else { this.y--; } - this.state = normal; }; @@ -2218,7 +2215,6 @@ Terminal.prototype.reset = function() { */ Terminal.prototype.tabSet = function() { this.tabs[this.x] = true; - this.state = normal; }; From 672dc1a251e01c7374c741d96f98b3def2d4a90d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 15:11:05 -0800 Subject: [PATCH 024/211] Start pulling CSI handlers out --- src/Parser.ts | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 42d429a3..9e02818d 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -12,6 +12,22 @@ normalStateHandler[C0.BS] = (handler) => handler.backspace(); normalStateHandler[C0.HT] = (handler) => handler.tab(); normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); +// TODO: Add ESC and Default cases to normalStateHandler + +const csiStateHandler: {[key: string]: (handler: IInputHandler, parser: Parser) => void} = {}; +csiStateHandler['?'] = (_, parser) => parser.setPrefix('?'); +csiStateHandler['>'] = (_, parser) => parser.setPrefix('>'); +csiStateHandler['!'] = (_, parser) => parser.setPrefix('!'); +csiStateHandler['0'] = (_, parser) => parser.setParam(parser.getParam() * 10); +csiStateHandler['1'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 1); +csiStateHandler['2'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 2); +csiStateHandler['3'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 3); +csiStateHandler['4'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 4); +csiStateHandler['5'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 5); +csiStateHandler['6'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 6); +csiStateHandler['7'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 7); +csiStateHandler['8'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 8); +csiStateHandler['9'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 9); enum ParserState { NORMAL = 0, @@ -487,15 +503,9 @@ export class Parser { break; case ParserState.CSI: - // '?', '>', '!' - if (ch === '?' || ch === '>' || ch === '!') { - this._terminal.prefix = ch; - break; - } - - // 0 - 9 - if (ch >= '0' && ch <= '9') { - this._terminal.currentParam = this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; + if (ch in csiStateHandler) { + csiStateHandler[ch](this._inputHandler, this); + // Skip below switch as this has handled these codes (eventually everything will be handled here break; } @@ -1036,6 +1046,18 @@ export class Parser { } } } + + public setPrefix(prefix: string) { + this._terminal.prefix = prefix; + } + + public setParam(param: number) { + this._terminal.currentParam = param; + } + + public getParam(): number { + return this._terminal.currentParam; + } } const wcwidth = (function(opts) { From 635a4d76822c2e4a9e651eed2f7e54e47879261e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 15:19:29 -0800 Subject: [PATCH 025/211] Handle CSI postfix --- src/Parser.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 9e02818d..789688fc 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -28,6 +28,11 @@ csiStateHandler['6'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 6 csiStateHandler['7'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 7); csiStateHandler['8'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 8); csiStateHandler['9'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 9); +csiStateHandler['$'] = (_, parser) => parser.setPostfix('$'); +csiStateHandler['"'] = (_, parser) => parser.setPostfix('"'); +csiStateHandler[' '] = (_, parser) => parser.setPostfix(' '); +csiStateHandler['\''] = (_, parser) => parser.setPostfix('\''); +// TODO: Add remaining CSI cases enum ParserState { NORMAL = 0, @@ -509,12 +514,6 @@ export class Parser { break; } - // '$', '"', ' ', '\'' - if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { - this._terminal.postfix = ch; - break; - } - this._terminal.params.push(this._terminal.currentParam); this._terminal.currentParam = 0; @@ -1047,7 +1046,7 @@ export class Parser { } } - public setPrefix(prefix: string) { + public setPrefix(prefix: string): void { this._terminal.prefix = prefix; } @@ -1058,6 +1057,10 @@ export class Parser { public getParam(): number { return this._terminal.currentParam; } + + public setPostfix(postfix: string): void { + this._terminal.postfix = postfix; + } } const wcwidth = (function(opts) { From 9942477bff3fe22e2858341ed3d10daffacc2878 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 15:38:54 -0800 Subject: [PATCH 026/211] Start converting CSI codes --- src/InputHandler.ts | 44 +++++++++++++++++++++++++ src/Interfaces.ts | 5 +++ src/Parser.ts | 80 ++++++++++++++++++++------------------------- src/xterm.js | 51 ----------------------------- 4 files changed, 84 insertions(+), 96 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 38b85367..064bb177 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -47,4 +47,48 @@ export class InputHandler implements IInputHandler { public shiftIn(): void { this._terminal.setgLevel(0); } + + public cursorUp(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y -= param; + if (this._terminal.y < 0) { + this._terminal.y = 0; + } + } + + public cursorDown(params: number[]) { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y += param; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + } + + public cursorForward(params: number[]) { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x += param; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + } + + public cursorBackward(params: number[]) { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x -= param; + if (this._terminal.x < 0) { + this._terminal.x = 0; + } + } } diff --git a/src/Interfaces.ts b/src/Interfaces.ts index ae05c79f..8eedab41 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -44,4 +44,9 @@ export interface IInputHandler { tab(): void; shiftOut(): void; shiftIn(): void; + // TODO: Make IInputHandler parameter names more friendly? (ie. cursorUp(amount: number)) + cursorUp(params: number[]): void; + cursorDown(params: number[]); + cursorForward(params: number[]); + cursorBackward(params: number[]); } diff --git a/src/Parser.ts b/src/Parser.ts index 789688fc..6bf89c4d 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -14,25 +14,31 @@ normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); // TODO: Add ESC and Default cases to normalStateHandler -const csiStateHandler: {[key: string]: (handler: IInputHandler, parser: Parser) => void} = {}; -csiStateHandler['?'] = (_, parser) => parser.setPrefix('?'); -csiStateHandler['>'] = (_, parser) => parser.setPrefix('>'); -csiStateHandler['!'] = (_, parser) => parser.setPrefix('!'); -csiStateHandler['0'] = (_, parser) => parser.setParam(parser.getParam() * 10); -csiStateHandler['1'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 1); -csiStateHandler['2'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 2); -csiStateHandler['3'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 3); -csiStateHandler['4'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 4); -csiStateHandler['5'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 5); -csiStateHandler['6'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 6); -csiStateHandler['7'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 7); -csiStateHandler['8'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 8); -csiStateHandler['9'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 9); -csiStateHandler['$'] = (_, parser) => parser.setPostfix('$'); -csiStateHandler['"'] = (_, parser) => parser.setPostfix('"'); -csiStateHandler[' '] = (_, parser) => parser.setPostfix(' '); -csiStateHandler['\''] = (_, parser) => parser.setPostfix('\''); -// TODO: Add remaining CSI cases +const csiParamStateHandler: {[key: string]: (handler: IInputHandler, parser: Parser) => void} = {}; +csiParamStateHandler['?'] = (_, parser) => parser.setPrefix('?'); +csiParamStateHandler['>'] = (_, parser) => parser.setPrefix('>'); +csiParamStateHandler['!'] = (_, parser) => parser.setPrefix('!'); +csiParamStateHandler['0'] = (_, parser) => parser.setParam(parser.getParam() * 10); +csiParamStateHandler['1'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 1); +csiParamStateHandler['2'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 2); +csiParamStateHandler['3'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 3); +csiParamStateHandler['4'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 4); +csiParamStateHandler['5'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 5); +csiParamStateHandler['6'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 6); +csiParamStateHandler['7'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 7); +csiParamStateHandler['8'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 8); +csiParamStateHandler['9'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 9); +csiParamStateHandler['$'] = (_, parser) => parser.setPostfix('$'); +csiParamStateHandler['"'] = (_, parser) => parser.setPostfix('"'); +csiParamStateHandler[' '] = (_, parser) => parser.setPostfix(' '); +csiParamStateHandler['\''] = (_, parser) => parser.setPostfix('\''); +// TODO: Handle ';' and default (move on to ParserState.CSI (from CSI_PARAM) + +const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[]) => void} = {}; +csiStateHandler['A'] = (handler, params) => handler.cursorUp(params); +csiStateHandler['B'] = (handler, params) => handler.cursorDown(params); +csiStateHandler['C'] = (handler, params) => handler.cursorForward(params); +csiStateHandler['D'] = (handler, params) => handler.cursorBackward(params); enum ParserState { NORMAL = 0, @@ -508,12 +514,14 @@ export class Parser { break; case ParserState.CSI: - if (ch in csiStateHandler) { - csiStateHandler[ch](this._inputHandler, this); + if (ch in csiParamStateHandler) { + csiParamStateHandler[ch](this._inputHandler, this); // Skip below switch as this has handled these codes (eventually everything will be handled here break; } + // TODO: a new state should be introduced? to differentiate checking for params and the codes + this._terminal.params.push(this._terminal.currentParam); this._terminal.currentParam = 0; @@ -522,31 +530,13 @@ export class Parser { this.state = ParserState.NORMAL; + if (ch in csiStateHandler) { + csiStateHandler[ch](this._inputHandler, this._terminal.params); + // Skip below switch as this has handled these codes (eventually everything will be handled here + break; + } + switch (ch) { - // CSI Ps A - // Cursor Up Ps Times (default = 1) (CUU). - case 'A': - this._terminal.cursorUp(this._terminal.params); - break; - - // CSI Ps B - // Cursor Down Ps Times (default = 1) (CUD). - case 'B': - this._terminal.cursorDown(this._terminal.params); - break; - - // CSI Ps C - // Cursor Forward Ps Times (default = 1) (CUF). - case 'C': - this._terminal.cursorForward(this._terminal.params); - break; - - // CSI Ps D - // Cursor Backward Ps Times (default = 1) (CUB). - case 'D': - this._terminal.cursorBackward(this._terminal.params); - break; - // CSI Ps ; Ps H // Cursor Position [row;column] (default = [1,1]) (CUP). case 'H': diff --git a/src/xterm.js b/src/xterm.js index bf9f9853..c3ef9bd6 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2222,57 +2222,6 @@ Terminal.prototype.tabSet = function() { * CSI */ -/** - * CSI Ps A - * Cursor Up Ps Times (default = 1) (CUU). - */ -Terminal.prototype.cursorUp = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.y -= param; - if (this.y < 0) this.y = 0; -}; - - -/** - * CSI Ps B - * Cursor Down Ps Times (default = 1) (CUD). - */ -Terminal.prototype.cursorDown = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.y += param; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } -}; - - -/** - * CSI Ps C - * Cursor Forward Ps Times (default = 1) (CUF). - */ -Terminal.prototype.cursorForward = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.x += param; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; - - -/** - * CSI Ps D - * Cursor Backward Ps Times (default = 1) (CUB). - */ -Terminal.prototype.cursorBackward = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.x -= param; - if (this.x < 0) this.x = 0; -}; - /** * CSI Ps ; Ps H From 7572dd5fa6aa76f195d2c98f3a0c632311227f9a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 15:39:42 -0800 Subject: [PATCH 027/211] Remove IInputHandler from CSI_PARAM lambdas --- src/Parser.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 6bf89c4d..3cfed5bb 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -14,24 +14,24 @@ normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); // TODO: Add ESC and Default cases to normalStateHandler -const csiParamStateHandler: {[key: string]: (handler: IInputHandler, parser: Parser) => void} = {}; -csiParamStateHandler['?'] = (_, parser) => parser.setPrefix('?'); -csiParamStateHandler['>'] = (_, parser) => parser.setPrefix('>'); -csiParamStateHandler['!'] = (_, parser) => parser.setPrefix('!'); -csiParamStateHandler['0'] = (_, parser) => parser.setParam(parser.getParam() * 10); -csiParamStateHandler['1'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 1); -csiParamStateHandler['2'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 2); -csiParamStateHandler['3'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 3); -csiParamStateHandler['4'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 4); -csiParamStateHandler['5'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 5); -csiParamStateHandler['6'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 6); -csiParamStateHandler['7'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 7); -csiParamStateHandler['8'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 8); -csiParamStateHandler['9'] = (_, parser) => parser.setParam(parser.getParam() * 10 + 9); -csiParamStateHandler['$'] = (_, parser) => parser.setPostfix('$'); -csiParamStateHandler['"'] = (_, parser) => parser.setPostfix('"'); -csiParamStateHandler[' '] = (_, parser) => parser.setPostfix(' '); -csiParamStateHandler['\''] = (_, parser) => parser.setPostfix('\''); +const csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {}; +csiParamStateHandler['?'] = (parser) => parser.setPrefix('?'); +csiParamStateHandler['>'] = (parser) => parser.setPrefix('>'); +csiParamStateHandler['!'] = (parser) => parser.setPrefix('!'); +csiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10); +csiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1); +csiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2); +csiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3); +csiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4); +csiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5); +csiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6); +csiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7); +csiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8); +csiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9); +csiParamStateHandler['$'] = (parser) => parser.setPostfix('$'); +csiParamStateHandler['"'] = (parser) => parser.setPostfix('"'); +csiParamStateHandler[' '] = (parser) => parser.setPostfix(' '); +csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); // TODO: Handle ';' and default (move on to ParserState.CSI (from CSI_PARAM) const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[]) => void} = {}; @@ -515,7 +515,7 @@ export class Parser { case ParserState.CSI: if (ch in csiParamStateHandler) { - csiParamStateHandler[ch](this._inputHandler, this); + csiParamStateHandler[ch](this); // Skip below switch as this has handled these codes (eventually everything will be handled here break; } From c7fa2d55b45d08442a1e33f3e5fd5af0ddc504ba Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 16:07:27 -0800 Subject: [PATCH 028/211] Handle remaining CSI_PARAM cases and introduce the state --- src/Parser.ts | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 3cfed5bb..afdbc007 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -32,7 +32,7 @@ csiParamStateHandler['$'] = (parser) => parser.setPostfix('$'); csiParamStateHandler['"'] = (parser) => parser.setPostfix('"'); csiParamStateHandler[' '] = (parser) => parser.setPostfix(' '); csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); -// TODO: Handle ';' and default (move on to ParserState.CSI (from CSI_PARAM) +csiParamStateHandler[';'] = (parser) => parser.finalizeParam(); const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[]) => void} = {}; csiStateHandler['A'] = (handler, params) => handler.cursorUp(params); @@ -43,11 +43,12 @@ csiStateHandler['D'] = (handler, params) => handler.cursorBackward(params); enum ParserState { NORMAL = 0, ESCAPED = 1, - CSI = 2, - OSC = 3, - CHARSET = 4, - DCS = 5, - IGNORE = 6 + CSI_PARAM = 2, + CSI = 3, + OSC = 4, + CHARSET = 5, + DCS = 6, + IGNORE = 7 } export class Parser { @@ -194,7 +195,7 @@ export class Parser { case '[': this._terminal.params = []; this._terminal.currentParam = 0; - this.state = ParserState.CSI; + this.state = ParserState.CSI_PARAM; break; // ESC ] Operating System Command ( OSC is 0x9d). @@ -513,21 +514,16 @@ export class Parser { } break; - case ParserState.CSI: + case ParserState.CSI_PARAM: if (ch in csiParamStateHandler) { csiParamStateHandler[ch](this); - // Skip below switch as this has handled these codes (eventually everything will be handled here break; } + this.finalizeParam(); + // Fall through the CSI as this character should be the CSI code. + this.state = ParserState.CSI; - // TODO: a new state should be introduced? to differentiate checking for params and the codes - - this._terminal.params.push(this._terminal.currentParam); - this._terminal.currentParam = 0; - - // ';' - if (ch === ';') break; - + case ParserState.CSI: this.state = ParserState.NORMAL; if (ch in csiStateHandler) { @@ -1048,6 +1044,11 @@ export class Parser { return this._terminal.currentParam; } + public finalizeParam(): void { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = 0; + } + public setPostfix(postfix: string): void { this._terminal.postfix = postfix; } From db81c28bd7a730832b62b82fec1590bc4a9b581f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 22:57:38 -0800 Subject: [PATCH 029/211] Support more CSI codes, remove unused CSI helper functions --- src/InputHandler.ts | 395 ++++++++++++++++++++++++++++++++++++++++++++ src/Interfaces.ts | 6 +- src/Parser.ts | 34 +--- src/xterm.js | 355 +-------------------------------------- 4 files changed, 408 insertions(+), 382 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 064bb177..a0bb61b9 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1,9 +1,14 @@ import { IInputHandler, ITerminal } from './Interfaces'; +import { C0 } from './EscapeSequences'; export class InputHandler implements IInputHandler { // TODO: We want to type _terminal when it's pulled into TS constructor(private _terminal: any) { } + /** + * BEL + * Bell (Ctrl-G). + */ public bell(): void { if (!this._terminal.visualBell) { return; @@ -15,6 +20,10 @@ export class InputHandler implements IInputHandler { } } + /** + * LF + * Line Feed or New Line (NL). (LF is Ctrl-J). + */ public lineFeed(): void { if (this._terminal.convertEol) { this._terminal.x = 0; @@ -26,28 +35,54 @@ export class InputHandler implements IInputHandler { } } + /** + * CR + * Carriage Return (Ctrl-M). + */ public carriageReturn(): void { this._terminal.x = 0; } + /** + * BS + * Backspace (Ctrl-H). + */ public backspace(): void { if (this._terminal.x > 0) { this._terminal.x--; } } + /** + * TAB + * Horizontal Tab (HT) (Ctrl-I). + */ public tab(): void { this._terminal.x = this._terminal.nextStop(); } + /** + * SO + * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the + * G1 character set. + */ public shiftOut(): void { this._terminal.setgLevel(1); } + /** + * SI + * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0 + * character set (the default). + */ public shiftIn(): void { this._terminal.setgLevel(0); } + /** + * CSI Ps A + * Cursor Up Ps Times (default = 1) (CUU). + */ public cursorUp(params: number[]): void { let param = params[0]; if (param < 1) { @@ -59,6 +94,10 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps B + * Cursor Down Ps Times (default = 1) (CUD). + */ public cursorDown(params: number[]) { let param = params[0]; if (param < 1) { @@ -70,6 +109,10 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps C + * Cursor Forward Ps Times (default = 1) (CUF). + */ public cursorForward(params: number[]) { let param = params[0]; if (param < 1) { @@ -81,6 +124,10 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps D + * Cursor Backward Ps Times (default = 1) (CUB). + */ public cursorBackward(params: number[]) { let param = params[0]; if (param < 1) { @@ -91,4 +138,352 @@ export class InputHandler implements IInputHandler { this._terminal.x = 0; } } + + /** + * CSI Ps ; Ps H + * Cursor Position [row;column] (default = [1,1]) (CUP). + */ + public cursorPosition(params: number[]) { + let row, col; + + row = params[0] - 1; + + if (params.length >= 2) { + col = params[1] - 1; + } else { + col = 0; + } + + if (row < 0) { + row = 0; + } else if (row >= this._terminal.rows) { + row = this._terminal.rows - 1; + } + + if (col < 0) { + col = 0; + } else if (col >= this._terminal.cols) { + col = this._terminal.cols - 1; + } + + this._terminal.x = col; + this._terminal.y = row; + } + + /** + * CSI Ps J Erase in Display (ED). + * Ps = 0 -> Erase Below (default). + * Ps = 1 -> Erase Above. + * Ps = 2 -> Erase All. + * Ps = 3 -> Erase Saved Lines (xterm). + * CSI ? Ps J + * Erase in Display (DECSED). + * Ps = 0 -> Selective Erase Below (default). + * Ps = 1 -> Selective Erase Above. + * Ps = 2 -> Selective Erase All. + */ + public eraseInDisplay(params: number[]) { + let j; + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.x, this._terminal.y); + j = this._terminal.y + 1; + for (; j < this._terminal.rows; j++) { + this._terminal.eraseLine(j); + } + break; + case 1: + this._terminal.eraseLeft(this._terminal.x, this._terminal.y); + j = this._terminal.y; + while (j--) { + this._terminal.eraseLine(j); + } + break; + case 2: + j = this._terminal.rows; + while (j--) this._terminal.eraseLine(j); + break; + case 3: + ; // no saved lines + break; + } + } + + /** + * CSI Ps K Erase in Line (EL). + * Ps = 0 -> Erase to Right (default). + * Ps = 1 -> Erase to Left. + * Ps = 2 -> Erase All. + * CSI ? Ps K + * Erase in Line (DECSEL). + * Ps = 0 -> Selective Erase to Right (default). + * Ps = 1 -> Selective Erase to Left. + * Ps = 2 -> Selective Erase All. + */ + public eraseInLine(params: number[]) { + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.x, this._terminal.y); + break; + case 1: + this._terminal.eraseLeft(this._terminal.x, this._terminal.y); + break; + case 2: + this._terminal.eraseLine(this._terminal.y); + break; + } + } + + /** + * CSI Pm m Character Attributes (SGR). + * Ps = 0 -> Normal (default). + * Ps = 1 -> Bold. + * Ps = 4 -> Underlined. + * Ps = 5 -> Blink (appears as Bold). + * Ps = 7 -> Inverse. + * Ps = 8 -> Invisible, i.e., hidden (VT300). + * Ps = 2 2 -> Normal (neither bold nor faint). + * Ps = 2 4 -> Not underlined. + * Ps = 2 5 -> Steady (not blinking). + * Ps = 2 7 -> Positive (not inverse). + * Ps = 2 8 -> Visible, i.e., not hidden (VT300). + * Ps = 3 0 -> Set foreground color to Black. + * Ps = 3 1 -> Set foreground color to Red. + * Ps = 3 2 -> Set foreground color to Green. + * Ps = 3 3 -> Set foreground color to Yellow. + * Ps = 3 4 -> Set foreground color to Blue. + * Ps = 3 5 -> Set foreground color to Magenta. + * Ps = 3 6 -> Set foreground color to Cyan. + * Ps = 3 7 -> Set foreground color to White. + * Ps = 3 9 -> Set foreground color to default (original). + * Ps = 4 0 -> Set background color to Black. + * Ps = 4 1 -> Set background color to Red. + * Ps = 4 2 -> Set background color to Green. + * Ps = 4 3 -> Set background color to Yellow. + * Ps = 4 4 -> Set background color to Blue. + * Ps = 4 5 -> Set background color to Magenta. + * Ps = 4 6 -> Set background color to Cyan. + * Ps = 4 7 -> Set background color to White. + * Ps = 4 9 -> Set background color to default (original). + * + * If 16-color support is compiled, the following apply. Assume + * that xterm's resources are set so that the ISO color codes are + * the first 8 of a set of 16. Then the aixterm colors are the + * bright versions of the ISO colors: + * Ps = 9 0 -> Set foreground color to Black. + * Ps = 9 1 -> Set foreground color to Red. + * Ps = 9 2 -> Set foreground color to Green. + * Ps = 9 3 -> Set foreground color to Yellow. + * Ps = 9 4 -> Set foreground color to Blue. + * Ps = 9 5 -> Set foreground color to Magenta. + * Ps = 9 6 -> Set foreground color to Cyan. + * Ps = 9 7 -> Set foreground color to White. + * Ps = 1 0 0 -> Set background color to Black. + * Ps = 1 0 1 -> Set background color to Red. + * Ps = 1 0 2 -> Set background color to Green. + * Ps = 1 0 3 -> Set background color to Yellow. + * Ps = 1 0 4 -> Set background color to Blue. + * Ps = 1 0 5 -> Set background color to Magenta. + * Ps = 1 0 6 -> Set background color to Cyan. + * Ps = 1 0 7 -> Set background color to White. + * + * If xterm is compiled with the 16-color support disabled, it + * supports the following, from rxvt: + * Ps = 1 0 0 -> Set foreground and background color to + * default. + * + * If 88- or 256-color support is compiled, the following apply. + * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second + * Ps. + * Ps = 4 8 ; 5 ; Ps -> Set background color to the second + * Ps. + */ + public charAttributes(params: number[]) { + // Optimize a single SGR0. + if (params.length === 1 && params[0] === 0) { + this._terminal.curAttr = this._terminal.defAttr; + return; + } + + let l = params.length + , i = 0 + , flags = this._terminal.curAttr >> 18 + , fg = (this._terminal.curAttr >> 9) & 0x1ff + , bg = this._terminal.curAttr & 0x1ff + , p; + + for (; i < l; i++) { + p = params[i]; + if (p >= 30 && p <= 37) { + // fg color 8 + fg = p - 30; + } else if (p >= 40 && p <= 47) { + // bg color 8 + bg = p - 40; + } else if (p >= 90 && p <= 97) { + // fg color 16 + p += 8; + fg = p - 90; + } else if (p >= 100 && p <= 107) { + // bg color 16 + p += 8; + bg = p - 100; + } else if (p === 0) { + // default + flags = this._terminal.defAttr >> 18; + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + // flags = 0; + // fg = 0x1ff; + // bg = 0x1ff; + } else if (p === 1) { + // bold text + flags |= 1; + } else if (p === 4) { + // underlined text + flags |= 2; + } else if (p === 5) { + // blink + flags |= 4; + } else if (p === 7) { + // inverse and positive + // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m' + flags |= 8; + } else if (p === 8) { + // invisible + flags |= 16; + } else if (p === 22) { + // not bold + flags &= ~1; + } else if (p === 24) { + // not underlined + flags &= ~2; + } else if (p === 25) { + // not blink + flags &= ~4; + } else if (p === 27) { + // not inverse + flags &= ~8; + } else if (p === 28) { + // not invisible + flags &= ~16; + } else if (p === 39) { + // reset fg + fg = (this._terminal.defAttr >> 9) & 0x1ff; + } else if (p === 49) { + // reset bg + bg = this._terminal.defAttr & 0x1ff; + } else if (p === 38) { + // fg color 256 + if (params[i + 1] === 2) { + i += 2; + fg = this._terminal.matchColor( + params[i] & 0xff, + params[i + 1] & 0xff, + params[i + 2] & 0xff); + if (fg === -1) fg = 0x1ff; + i += 2; + } else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } + } else if (p === 48) { + // bg color 256 + if (params[i + 1] === 2) { + i += 2; + bg = this._terminal.matchColor( + params[i] & 0xff, + params[i + 1] & 0xff, + params[i + 2] & 0xff); + if (bg === -1) bg = 0x1ff; + i += 2; + } else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } + } else if (p === 100) { + // reset fg/bg + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } else { + this._terminal.error('Unknown SGR attribute: %d.', p); + } + } + + this._terminal.curAttr = (flags << 18) | (fg << 9) | bg; + } + + /** + * CSI Ps n Device Status Report (DSR). + * Ps = 5 -> Status Report. Result (``OK'') is + * CSI 0 n + * Ps = 6 -> Report Cursor Position (CPR) [row;column]. + * Result is + * CSI r ; c R + * CSI ? Ps n + * Device Status Report (DSR, DEC-specific). + * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI + * ? r ; c R (assumes page is zero). + * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready). + * or CSI ? 1 1 n (not ready). + * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked) + * or CSI ? 2 1 n (locked). + * Ps = 2 6 -> Report Keyboard status as + * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American). + * The last two parameters apply to VT400 & up, and denote key- + * board ready and LK01 respectively. + * Ps = 5 3 -> Report Locator status as + * CSI ? 5 3 n Locator available, if compiled-in, or + * CSI ? 5 0 n No Locator, if not. + */ + public deviceStatus(params: number[]) { + if (!this._terminal.prefix) { + switch (params[0]) { + case 5: + // status report + this._terminal.send(C0.ESC + '[0n'); + break; + case 6: + // cursor position + this._terminal.send(C0.ESC + '[' + + (this._terminal.y + 1) + + ';' + + (this._terminal.x + 1) + + 'R'); + break; + } + } else if (this._terminal.prefix === '?') { + // modern xterm doesnt seem to + // respond to any of these except ?6, 6, and 5 + switch (params[0]) { + case 6: + // cursor position + this._terminal.send(C0.ESC + '[?' + + (this._terminal.y + 1) + + ';' + + (this._terminal.x + 1) + + 'R'); + break; + case 15: + // no printer + // this.send(C0.ESC + '[?11n'); + break; + case 25: + // dont support user defined keys + // this.send(C0.ESC + '[?21n'); + break; + case 26: + // north american keyboard + // this.send(C0.ESC + '[?27;1;0;0n'); + break; + case 53: + // no dec locator/mouse + // this.send(C0.ESC + '[?50n'); + break; + } + } + } + } diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 8eedab41..e54a58bf 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -44,9 +44,13 @@ export interface IInputHandler { tab(): void; shiftOut(): void; shiftIn(): void; - // TODO: Make IInputHandler parameter names more friendly? (ie. cursorUp(amount: number)) cursorUp(params: number[]): void; cursorDown(params: number[]); cursorForward(params: number[]); cursorBackward(params: number[]); + cursorPosition(params: number[]); + eraseInDisplay(params: number[]); + eraseInLine(params: number[]); + charAttributes(params: number[]); + deviceStatus(params: number[]); } diff --git a/src/Parser.ts b/src/Parser.ts index afdbc007..e6f6c772 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -39,6 +39,11 @@ csiStateHandler['A'] = (handler, params) => handler.cursorUp(params); csiStateHandler['B'] = (handler, params) => handler.cursorDown(params); csiStateHandler['C'] = (handler, params) => handler.cursorForward(params); csiStateHandler['D'] = (handler, params) => handler.cursorBackward(params); +csiStateHandler['H'] = (handler, params) => handler.cursorPosition(params); +csiStateHandler['J'] = (handler, params) => handler.eraseInDisplay(params); +csiStateHandler['K'] = (handler, params) => handler.eraseInLine(params); +csiStateHandler['m'] = (handler, params) => handler.charAttributes(params); +csiStateHandler['n'] = (handler, params) => handler.deviceStatus(params); enum ParserState { NORMAL = 0, @@ -533,35 +538,6 @@ export class Parser { } switch (ch) { - // CSI Ps ; Ps H - // Cursor Position [row;column] (default = [1,1]) (CUP). - case 'H': - this._terminal.cursorPos(this._terminal.params); - break; - - // CSI Ps J Erase in Display (ED). - case 'J': - this._terminal.eraseInDisplay(this._terminal.params); - break; - - // CSI Ps K Erase in Line (EL). - case 'K': - this._terminal.eraseInLine(this._terminal.params); - break; - - // CSI Pm m Character Attributes (SGR). - case 'm': - if (!this._terminal.prefix) { - this._terminal.charAttributes(this._terminal.params); - } - break; - - // CSI Ps n Device Status Report (DSR). - case 'n': - if (!this._terminal.prefix) { - this._terminal.deviceStatus(this._terminal.params); - } - break; /** * Additions diff --git a/src/xterm.js b/src/xterm.js index c3ef9bd6..723de055 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2223,358 +2223,6 @@ Terminal.prototype.tabSet = function() { */ -/** - * CSI Ps ; Ps H - * Cursor Position [row;column] (default = [1,1]) (CUP). - */ -Terminal.prototype.cursorPos = function(params) { - var row, col; - - row = params[0] - 1; - - if (params.length >= 2) { - col = params[1] - 1; - } else { - col = 0; - } - - if (row < 0) { - row = 0; - } else if (row >= this.rows) { - row = this.rows - 1; - } - - if (col < 0) { - col = 0; - } else if (col >= this.cols) { - col = this.cols - 1; - } - - this.x = col; - this.y = row; -}; - - -/** - * CSI Ps J Erase in Display (ED). - * Ps = 0 -> Erase Below (default). - * Ps = 1 -> Erase Above. - * Ps = 2 -> Erase All. - * Ps = 3 -> Erase Saved Lines (xterm). - * CSI ? Ps J - * Erase in Display (DECSED). - * Ps = 0 -> Selective Erase Below (default). - * Ps = 1 -> Selective Erase Above. - * Ps = 2 -> Selective Erase All. - */ -Terminal.prototype.eraseInDisplay = function(params) { - var j; - switch (params[0]) { - case 0: - this.eraseRight(this.x, this.y); - j = this.y + 1; - for (; j < this.rows; j++) { - this.eraseLine(j); - } - break; - case 1: - this.eraseLeft(this.x, this.y); - j = this.y; - while (j--) { - this.eraseLine(j); - } - break; - case 2: - j = this.rows; - while (j--) this.eraseLine(j); - break; - case 3: - ; // no saved lines - break; - } -}; - - -/** - * CSI Ps K Erase in Line (EL). - * Ps = 0 -> Erase to Right (default). - * Ps = 1 -> Erase to Left. - * Ps = 2 -> Erase All. - * CSI ? Ps K - * Erase in Line (DECSEL). - * Ps = 0 -> Selective Erase to Right (default). - * Ps = 1 -> Selective Erase to Left. - * Ps = 2 -> Selective Erase All. - */ -Terminal.prototype.eraseInLine = function(params) { - switch (params[0]) { - case 0: - this.eraseRight(this.x, this.y); - break; - case 1: - this.eraseLeft(this.x, this.y); - break; - case 2: - this.eraseLine(this.y); - break; - } -}; - - -/** - * CSI Pm m Character Attributes (SGR). - * Ps = 0 -> Normal (default). - * Ps = 1 -> Bold. - * Ps = 4 -> Underlined. - * Ps = 5 -> Blink (appears as Bold). - * Ps = 7 -> Inverse. - * Ps = 8 -> Invisible, i.e., hidden (VT300). - * Ps = 2 2 -> Normal (neither bold nor faint). - * Ps = 2 4 -> Not underlined. - * Ps = 2 5 -> Steady (not blinking). - * Ps = 2 7 -> Positive (not inverse). - * Ps = 2 8 -> Visible, i.e., not hidden (VT300). - * Ps = 3 0 -> Set foreground color to Black. - * Ps = 3 1 -> Set foreground color to Red. - * Ps = 3 2 -> Set foreground color to Green. - * Ps = 3 3 -> Set foreground color to Yellow. - * Ps = 3 4 -> Set foreground color to Blue. - * Ps = 3 5 -> Set foreground color to Magenta. - * Ps = 3 6 -> Set foreground color to Cyan. - * Ps = 3 7 -> Set foreground color to White. - * Ps = 3 9 -> Set foreground color to default (original). - * Ps = 4 0 -> Set background color to Black. - * Ps = 4 1 -> Set background color to Red. - * Ps = 4 2 -> Set background color to Green. - * Ps = 4 3 -> Set background color to Yellow. - * Ps = 4 4 -> Set background color to Blue. - * Ps = 4 5 -> Set background color to Magenta. - * Ps = 4 6 -> Set background color to Cyan. - * Ps = 4 7 -> Set background color to White. - * Ps = 4 9 -> Set background color to default (original). - * - * If 16-color support is compiled, the following apply. Assume - * that xterm's resources are set so that the ISO color codes are - * the first 8 of a set of 16. Then the aixterm colors are the - * bright versions of the ISO colors: - * Ps = 9 0 -> Set foreground color to Black. - * Ps = 9 1 -> Set foreground color to Red. - * Ps = 9 2 -> Set foreground color to Green. - * Ps = 9 3 -> Set foreground color to Yellow. - * Ps = 9 4 -> Set foreground color to Blue. - * Ps = 9 5 -> Set foreground color to Magenta. - * Ps = 9 6 -> Set foreground color to Cyan. - * Ps = 9 7 -> Set foreground color to White. - * Ps = 1 0 0 -> Set background color to Black. - * Ps = 1 0 1 -> Set background color to Red. - * Ps = 1 0 2 -> Set background color to Green. - * Ps = 1 0 3 -> Set background color to Yellow. - * Ps = 1 0 4 -> Set background color to Blue. - * Ps = 1 0 5 -> Set background color to Magenta. - * Ps = 1 0 6 -> Set background color to Cyan. - * Ps = 1 0 7 -> Set background color to White. - * - * If xterm is compiled with the 16-color support disabled, it - * supports the following, from rxvt: - * Ps = 1 0 0 -> Set foreground and background color to - * default. - * - * If 88- or 256-color support is compiled, the following apply. - * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second - * Ps. - * Ps = 4 8 ; 5 ; Ps -> Set background color to the second - * Ps. - */ -Terminal.prototype.charAttributes = function(params) { - // Optimize a single SGR0. - if (params.length === 1 && params[0] === 0) { - this.curAttr = this.defAttr; - return; - } - - var l = params.length - , i = 0 - , flags = this.curAttr >> 18 - , fg = (this.curAttr >> 9) & 0x1ff - , bg = this.curAttr & 0x1ff - , p; - - for (; i < l; i++) { - p = params[i]; - if (p >= 30 && p <= 37) { - // fg color 8 - fg = p - 30; - } else if (p >= 40 && p <= 47) { - // bg color 8 - bg = p - 40; - } else if (p >= 90 && p <= 97) { - // fg color 16 - p += 8; - fg = p - 90; - } else if (p >= 100 && p <= 107) { - // bg color 16 - p += 8; - bg = p - 100; - } else if (p === 0) { - // default - flags = this.defAttr >> 18; - fg = (this.defAttr >> 9) & 0x1ff; - bg = this.defAttr & 0x1ff; - // flags = 0; - // fg = 0x1ff; - // bg = 0x1ff; - } else if (p === 1) { - // bold text - flags |= 1; - } else if (p === 4) { - // underlined text - flags |= 2; - } else if (p === 5) { - // blink - flags |= 4; - } else if (p === 7) { - // inverse and positive - // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m' - flags |= 8; - } else if (p === 8) { - // invisible - flags |= 16; - } else if (p === 22) { - // not bold - flags &= ~1; - } else if (p === 24) { - // not underlined - flags &= ~2; - } else if (p === 25) { - // not blink - flags &= ~4; - } else if (p === 27) { - // not inverse - flags &= ~8; - } else if (p === 28) { - // not invisible - flags &= ~16; - } else if (p === 39) { - // reset fg - fg = (this.defAttr >> 9) & 0x1ff; - } else if (p === 49) { - // reset bg - bg = this.defAttr & 0x1ff; - } else if (p === 38) { - // fg color 256 - if (params[i + 1] === 2) { - i += 2; - fg = matchColor( - params[i] & 0xff, - params[i + 1] & 0xff, - params[i + 2] & 0xff); - if (fg === -1) fg = 0x1ff; - i += 2; - } else if (params[i + 1] === 5) { - i += 2; - p = params[i] & 0xff; - fg = p; - } - } else if (p === 48) { - // bg color 256 - if (params[i + 1] === 2) { - i += 2; - bg = matchColor( - params[i] & 0xff, - params[i + 1] & 0xff, - params[i + 2] & 0xff); - if (bg === -1) bg = 0x1ff; - i += 2; - } else if (params[i + 1] === 5) { - i += 2; - p = params[i] & 0xff; - bg = p; - } - } else if (p === 100) { - // reset fg/bg - fg = (this.defAttr >> 9) & 0x1ff; - bg = this.defAttr & 0x1ff; - } else { - this.error('Unknown SGR attribute: %d.', p); - } - } - - this.curAttr = (flags << 18) | (fg << 9) | bg; -}; - - -/** - * CSI Ps n Device Status Report (DSR). - * Ps = 5 -> Status Report. Result (``OK'') is - * CSI 0 n - * Ps = 6 -> Report Cursor Position (CPR) [row;column]. - * Result is - * CSI r ; c R - * CSI ? Ps n - * Device Status Report (DSR, DEC-specific). - * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI - * ? r ; c R (assumes page is zero). - * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready). - * or CSI ? 1 1 n (not ready). - * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked) - * or CSI ? 2 1 n (locked). - * Ps = 2 6 -> Report Keyboard status as - * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American). - * The last two parameters apply to VT400 & up, and denote key- - * board ready and LK01 respectively. - * Ps = 5 3 -> Report Locator status as - * CSI ? 5 3 n Locator available, if compiled-in, or - * CSI ? 5 0 n No Locator, if not. - */ -Terminal.prototype.deviceStatus = function(params) { - if (!this.prefix) { - switch (params[0]) { - case 5: - // status report - this.send(C0.ESC + '[0n'); - break; - case 6: - // cursor position - this.send(C0.ESC + '[' - + (this.y + 1) - + ';' - + (this.x + 1) - + 'R'); - break; - } - } else if (this.prefix === '?') { - // modern xterm doesnt seem to - // respond to any of these except ?6, 6, and 5 - switch (params[0]) { - case 6: - // cursor position - this.send(C0.ESC + '[?' - + (this.y + 1) - + ';' - + (this.x + 1) - + 'R'); - break; - case 15: - // no printer - // this.send(C0.ESC + '[?11n'); - break; - case 25: - // dont support user defined keys - // this.send(C0.ESC + '[?21n'); - break; - case 26: - // north american keyboard - // this.send(C0.ESC + '[?27;1;0;0n'); - break; - case 53: - // no dec locator/mouse - // this.send(C0.ESC + '[?50n'); - break; - } - } -}; - - /** * Additions */ @@ -3849,6 +3497,9 @@ function isThirdLevelShift(term, ev) { return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); } +// Expose to InputHandler (temporary) +Terminal.prototype.matchColor = matchColor; + function matchColor(r1, g1, b1) { var hash = (r1 << 16) | (g1 << 8) | b1; From 411b80cdc0d46cda4472652a7fd17a8732ac6b7a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 9 Jan 2017 23:06:36 -0800 Subject: [PATCH 030/211] Add CSI @, E, F, G --- src/InputHandler.ts | 78 ++++++++++++++++++++++++++++++++++++++++++--- src/Interfaces.ts | 20 +++++++----- src/Parser.ts | 10 +++--- src/xterm.js | 60 ---------------------------------- 4 files changed, 89 insertions(+), 79 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index a0bb61b9..51c6a2d9 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -79,6 +79,26 @@ export class InputHandler implements IInputHandler { this._terminal.setgLevel(0); } + /** + * CSI Ps @ + * Insert Ps (Blank) Character(s) (default = 1) (ICH). + */ + public insertChars(params: number[]): void { + let param, row, j, ch; + + param = params[0]; + if (param < 1) param = 1; + + row = this._terminal.y + this._terminal.ybase; + j = this._terminal.x; + ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm + + while (param-- && j < this._terminal.cols) { + this._terminal.lines.get(row).splice(j++, 0, ch); + this._terminal.lines.get(row).pop(); + } + } + /** * CSI Ps A * Cursor Up Ps Times (default = 1) (CUU). @@ -139,11 +159,59 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps E + * Cursor Next Line Ps Times (default = 1) (CNL). + * same as CSI Ps B ? + */ + public cursorNextLine(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y += param; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + this._terminal.x = 0; + }; + + + /** + * CSI Ps F + * Cursor Preceding Line Ps Times (default = 1) (CNL). + * reuse CSI Ps A ? + */ + public cursorPrecedingLine(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y -= param; + if (this._terminal.y < 0) { + this._terminal.y = 0; + } + this._terminal.x = 0; + }; + + + /** + * CSI Ps G + * Cursor Character Absolute [column] (default = [row,1]) (CHA). + */ + public cursorCharAbsolute(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x = param - 1; + } + /** * CSI Ps ; Ps H * Cursor Position [row;column] (default = [1,1]) (CUP). */ - public cursorPosition(params: number[]) { + public cursorPosition(params: number[]): void { let row, col; row = params[0] - 1; @@ -182,7 +250,7 @@ export class InputHandler implements IInputHandler { * Ps = 1 -> Selective Erase Above. * Ps = 2 -> Selective Erase All. */ - public eraseInDisplay(params: number[]) { + public eraseInDisplay(params: number[]): void { let j; switch (params[0]) { case 0: @@ -220,7 +288,7 @@ export class InputHandler implements IInputHandler { * Ps = 1 -> Selective Erase to Left. * Ps = 2 -> Selective Erase All. */ - public eraseInLine(params: number[]) { + public eraseInLine(params: number[]): void { switch (params[0]) { case 0: this._terminal.eraseRight(this._terminal.x, this._terminal.y); @@ -298,7 +366,7 @@ export class InputHandler implements IInputHandler { * Ps = 4 8 ; 5 ; Ps -> Set background color to the second * Ps. */ - public charAttributes(params: number[]) { + public charAttributes(params: number[]): void { // Optimize a single SGR0. if (params.length === 1 && params[0] === 0) { this._terminal.curAttr = this._terminal.defAttr; @@ -438,7 +506,7 @@ export class InputHandler implements IInputHandler { * CSI ? 5 3 n Locator available, if compiled-in, or * CSI ? 5 0 n No Locator, if not. */ - public deviceStatus(params: number[]) { + public deviceStatus(params: number[]): void { if (!this._terminal.prefix) { switch (params[0]) { case 5: diff --git a/src/Interfaces.ts b/src/Interfaces.ts index e54a58bf..a2cb71a6 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -44,13 +44,17 @@ export interface IInputHandler { tab(): void; shiftOut(): void; shiftIn(): void; + insertChars(params); cursorUp(params: number[]): void; - cursorDown(params: number[]); - cursorForward(params: number[]); - cursorBackward(params: number[]); - cursorPosition(params: number[]); - eraseInDisplay(params: number[]); - eraseInLine(params: number[]); - charAttributes(params: number[]); - deviceStatus(params: number[]); + cursorDown(params: number[]): void; + cursorForward(params: number[]): void; + cursorBackward(params: number[]): void; + cursorNextLine(params: number[]): void; + cursorPrecedingLine(params: number[]): void; + cursorCharAbsolute(params: number[]): void; + cursorPosition(params: number[]): void; + eraseInDisplay(params: number[]): void; + eraseInLine(params: number[]): void; + charAttributes(params: number[]): void; + deviceStatus(params: number[]): void; } diff --git a/src/Parser.ts b/src/Parser.ts index e6f6c772..9a14bdfd 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -35,10 +35,14 @@ csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); csiParamStateHandler[';'] = (parser) => parser.finalizeParam(); const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[]) => void} = {}; +csiStateHandler['@'] = (handler, params) => handler.insertChars(params); csiStateHandler['A'] = (handler, params) => handler.cursorUp(params); csiStateHandler['B'] = (handler, params) => handler.cursorDown(params); csiStateHandler['C'] = (handler, params) => handler.cursorForward(params); csiStateHandler['D'] = (handler, params) => handler.cursorBackward(params); +csiStateHandler['E'] = (handler, params) => handler.cursorNextLine(params); +csiStateHandler['F'] = (handler, params) => handler.cursorPrecedingLine(params); +csiStateHandler['G'] = (handler, params) => handler.cursorCharAbsolute(params); csiStateHandler['H'] = (handler, params) => handler.cursorPosition(params); csiStateHandler['J'] = (handler, params) => handler.eraseInDisplay(params); csiStateHandler['K'] = (handler, params) => handler.eraseInLine(params); @@ -543,12 +547,6 @@ export class Parser { * Additions */ - // CSI Ps @ - // Insert Ps (Blank) Character(s) (default = 1) (ICH). - case '@': - this._terminal.insertChars(this._terminal.params); - break; - // CSI Ps E // Cursor Next Line Ps Times (default = 1) (CNL). case 'E': diff --git a/src/xterm.js b/src/xterm.js index 723de055..035ce101 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2227,66 +2227,6 @@ Terminal.prototype.tabSet = function() { * Additions */ -/** - * CSI Ps @ - * Insert Ps (Blank) Character(s) (default = 1) (ICH). - */ -Terminal.prototype.insertChars = function(params) { - var param, row, j, ch; - - param = params[0]; - if (param < 1) param = 1; - - row = this.y + this.ybase; - j = this.x; - ch = [this.eraseAttr(), ' ', 1]; // xterm - - while (param-- && j < this.cols) { - this.lines.get(row).splice(j++, 0, ch); - this.lines.get(row).pop(); - } -}; - -/** - * CSI Ps E - * Cursor Next Line Ps Times (default = 1) (CNL). - * same as CSI Ps B ? - */ -Terminal.prototype.cursorNextLine = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.y += param; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } - this.x = 0; -}; - - -/** - * CSI Ps F - * Cursor Preceding Line Ps Times (default = 1) (CNL). - * reuse CSI Ps A ? - */ -Terminal.prototype.cursorPrecedingLine = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.y -= param; - if (this.y < 0) this.y = 0; - this.x = 0; -}; - - -/** - * CSI Ps G - * Cursor Character Absolute [column] (default = [row,1]) (CHA). - */ -Terminal.prototype.cursorCharAbsolute = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.x = param - 1; -}; - /** * CSI Ps L From d9682bd6d6ad8dfff773bfa0bbb4a2289bc1f335 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 10 Jan 2017 11:36:21 -0800 Subject: [PATCH 031/211] Perform CharMeasure.measure async This fixes the edge case where getBoundingClientRect was returning a width and height of 0,0. Fixes #465 --- src/utils/CharMeasure.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/utils/CharMeasure.ts b/src/utils/CharMeasure.ts index 60684a2c..6ca5046a 100644 --- a/src/utils/CharMeasure.ts +++ b/src/utils/CharMeasure.ts @@ -28,24 +28,29 @@ export class CharMeasure extends EventEmitter { } public measure(): void { - const oldWidth = this._width; - const oldHeight = this._height; - if (!this._measureElement) { this._measureElement = document.createElement('span'); this._measureElement.style.position = 'absolute'; this._measureElement.style.top = '0'; this._measureElement.style.left = '-9999em'; this._measureElement.textContent = 'W'; + this._parentElement.appendChild(this._measureElement); + // Perform _doMeasure async if the element was just attached as sometimes + // getBoundingClientRect does not return accurate values without this. + setTimeout(() => this._doMeasure(), 0); + } else { + this._doMeasure(); } + } - this._parentElement.appendChild(this._measureElement); + private _doMeasure(): void { + const oldWidth = this._width; + const oldHeight = this._height; const geometry = this._measureElement.getBoundingClientRect(); - this._width = geometry.width; - this._height = geometry.height; - this._parentElement.removeChild(this._measureElement); - if (this._width !== oldWidth || this._height !== oldHeight) { + if (this._width !== geometry.width || this._height !== geometry.height) { + this._width = geometry.width; + this._height = geometry.height; this.emit('charsizechanged'); } } From 081fe3f301a9146ae7bc20e4392a7f012496314e Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Sat, 31 Dec 2016 11:52:26 +0200 Subject: [PATCH 032/211] Fix #359 - Introduce build system based on Gulp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Gulp and new dependencies to `package.json` - Add `gulpfile.js` with four tasks: - `tsc`: For building TypeScript sources - `bundle`: For bundling JavaScript modules in a monolith - `sorcery`: For resolving the source map chains back to the original TypeScript files - `build` (`default`): Runs the whole `tsc` → `bundle` → `sorcery` chain - Clean up `Dockerfile`, since `cpio` is not needed any more - Clean up not needed dependencies from `package.json` - Remove `bin/build` - Update `bin/release` to use `npm run build` instead of `./bin/build` --- Dockerfile | 5 --- bin/build | 36 ------------------- bin/prepare-release | 2 +- gulpfile.js | 87 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 14 ++++++-- src/xterm.js | 12 +++---- tsconfig.json | 8 +++-- 7 files changed, 111 insertions(+), 53 deletions(-) delete mode 100755 bin/build create mode 100644 gulpfile.js diff --git a/Dockerfile b/Dockerfile index 36e821bd..1f0db1f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,6 @@ FROM node:6.9 MAINTAINER Paris Kasidiaris -# Install cpio, used for building -RUN apt-get update \ - && apt-get install -y --no-install-recommends cpio \ - && rm -rf /var/lib/apt/lists/* - # Set the working directory WORKDIR /usr/src/app diff --git a/bin/build b/bin/build deleted file mode 100755 index a01a1b9f..00000000 --- a/bin/build +++ /dev/null @@ -1,36 +0,0 @@ -#! /usr/bin/env bash - -set -e - -# $BUILD_DIR should default to "build" -BUILD_DIR=${BUILD_DIR:=build} - -# Create the build directory -mkdir -p $BUILD_DIR - - -# Clean lib/* to prevent confusion if files were deleted in src/ -rm -rf lib/* - -# Build all TypeScript files (including tests) to lib/ -tsc - -# Concat all xterm.js files into a single file and output as a UMD to $BUILD_DIR/xterm.js -browserify ./lib/xterm.js --standalone Terminal --debug --outfile ./$BUILD_DIR/xterm.js -cat ./$BUILD_DIR/xterm.js | exorcist ./$BUILD_DIR/xterm.js.map -b ./$BUILD_DIR > ./$BUILD_DIR/xterm.temp.js -rm ./$BUILD_DIR/xterm.js -mv ./$BUILD_DIR/xterm.temp.js ./$BUILD_DIR/xterm.js - -# Resolve the chain of sourcemaps so that ./$BUILD_DIR/xterm.js.map points at ./src -sorcery -i $BUILD_DIR/xterm.js - -# Copy all CSS files from src/ to $BUILD_DIR/ and lib/ -cd src -find . -name '*.css' | cpio -pdm ../$BUILD_DIR -find . -name '*.css' | cpio -pdm ../lib -cd .. - -# Copy addons from lib/ to $BUILD_DIR/ -cd lib/addons -find . -name '*.js' | cpio -pdm ../../$BUILD_DIR/addons -cd ../.. diff --git a/bin/prepare-release b/bin/prepare-release index 6bd39d3d..464e65b4 100755 --- a/bin/prepare-release +++ b/bin/prepare-release @@ -21,7 +21,7 @@ CURRENT_BOWER_JSON_VERSION=$(cat bower.json \ # Build xterm.js into `dist` export BUILD_DIR=dist -./bin/build +npm run build # Update AUTHORS file sh bin/generate-authors diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..144b8831 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,87 @@ +const browserify = require('browserify'); +const buffer = require('vinyl-buffer'); +const fs = require('fs-extra'); +const gulp = require('gulp'); +const merge = require('merge-stream'); +const sorcery = require('sorcery'); +const source = require('vinyl-source-stream'); +const sourcemaps = require('gulp-sourcemaps'); +const ts = require('gulp-typescript'); +const tsify = require('tsify'); + + +let buildDir = process.env.BUILD_DIR || 'build'; + + +/** + * Compile TypeScript sources to JavaScript files and create a source map file for each TypeScript + * file compiled. + */ +gulp.task('tsc', function () { + // Remove the lib/ directory to prevent confusion if files were deleted in src/ + fs.emptyDirSync('lib'); + + // Build all TypeScript files (including tests) to lib/, based on the configuration defined in + // `tsconfig.json`. + let tsProject = ts.createProject('tsconfig.json'); + let tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject()); + let tsc = tsResult.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest('lib')); + + // Copy all addons from src/ to lib/ + let copyAddons = gulp.src('src/addons/**/*').pipe(gulp.dest('lib/addons')); + + // Copy stylesheets from src/ to lib/ + let copyStylesheets = gulp.src('src/**/*.css').pipe(gulp.dest('lib')); + + return merge(tsc, copyAddons, copyStylesheets); +}); + +/** + * Bundle JavaScript files produced by the `tsc` task, into a single file named `xterm.js` with + * Browserify. + */ +gulp.task('browserify', ['tsc'], function() { + // Ensure that the build directory exists + fs.ensureDirSync(buildDir); + + let browserifyOptions = { + basedir: buildDir, + debug: true, + entries: ['../lib/xterm.js'], + standalone: 'Terminal', + cache: {}, + packageCache: {} + }; + let bundleStream = browserify(browserifyOptions) + .plugin(tsify) + .bundle() + .pipe(source('xterm.js')) + .pipe(buffer()) + .pipe(sourcemaps.init({loadMaps: true, sourceRoot: '..'})) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(buildDir)); + + // Copy all add-ons from lib/ to buildDir + let copyAddons = gulp.src('lib/addons/**/*').pipe(gulp.dest(`${buildDir}/addons`)); + + // Copy stylesheets from src/ to lib/ + let copyStylesheets = gulp.src('lib/**/*.css').pipe(gulp.dest(buildDir)); + + return merge(bundleStream, copyAddons, copyStylesheets); +}); + + +/** + * Use `sorcery` to resolve the source map chain and point back to the TypeScript files. + * (Without this task the source maps produced for the JavaScript bundle points into the + * compiled JavaScript files in lib/). + */ +gulp.task('sorcery', ['browserify'], function () { + var chain = sorcery.loadSync(`${buildDir}/xterm.js`); + var map = chain.apply(); + chain.writeSync(); +}); + +gulp.task('build', ['sorcery']); + +gulp.task('default', ['build']); diff --git a/package.json b/package.json index 734bb6fb..d5071a70 100644 --- a/package.json +++ b/package.json @@ -38,18 +38,26 @@ "browserify": "^13.1.0", "chai": "3.5.0", "docdash": "0.4.0", - "exorcist": "^0.4.0", "express": "4.13.4", "express-ws": "2.0.0-rc.1", + "fs-extra": "^1.0.0", "glob": "^7.0.5", + "gulp": "^3.9.1", + "gulp-cli": "^1.2.2", + "gulp-sourcemaps": "^1.9.1", + "gulp-typescript": "^3.1.3", "jsdoc": "3.4.3", + "merge-stream": "^1.0.1", "mocha": "2.5.3", "nodemon": "1.10.2", "pty.js": "0.3.1", "sleep": "^3.0.1", "sorcery": "^0.10.0", + "tsify": "^3.0.0", "tslint": "^4.0.2", - "typescript": "^2.0.3" + "typescript": "^2.0.3", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0" }, "scripts": { "prestart": "npm run build", @@ -58,7 +66,7 @@ "lint": "tslint src/**/*.ts", "test": "mocha --recursive ./lib", "build:docs": "jsdoc -c jsdoc.json", - "build": "./bin/build", + "build": "gulp build", "prepublish": "npm run build" } } diff --git a/src/xterm.js b/src/xterm.js index b6c659c3..2fcf5073 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -10,13 +10,13 @@ * @license MIT */ -import { CompositionHelper } from './CompositionHelper.js'; -import { EventEmitter } from './EventEmitter.js'; -import { Viewport } from './Viewport.js'; -import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js'; -import { CircularList } from './utils/CircularList.js'; +import { CompositionHelper } from './CompositionHelper'; +import { EventEmitter } from './EventEmitter'; +import { Viewport } from './Viewport'; +import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard'; +import { CircularList } from './utils/CircularList'; import { C0 } from './EscapeSequences'; -import { CharMeasure } from './utils/CharMeasure.js'; +import { CharMeasure } from './utils/CharMeasure'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; diff --git a/tsconfig.json b/tsconfig.json index f4a5a1b2..f5a7d66c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,13 +7,17 @@ "outDir": "lib", "sourceMap": true }, + "include": [ + "src/**/*" + ], "exclude": [ - "addons", + "src/addons/**/*", "build", "demo", "dist", "out", "test", - "node_modules" + "node_modules", + "docs" ] } From 0f5f34e8f5367f10dc9fcf5a489f62f209f066cb Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 10:47:57 -0800 Subject: [PATCH 033/211] Move CharMeasure element to the helper container Fixes #470 --- src/xterm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index b6c659c3..b92736a9 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -614,7 +614,7 @@ Terminal.prototype.open = function(parent) { } this.parent.appendChild(this.element); - this.charMeasure = new CharMeasure(this.rowContainer); + this.charMeasure = new CharMeasure(this.helperContainer); this.charMeasure.on('charsizechanged', function () { self.updateCharSizeCSS(); }); From 23169e89c8c65464c8bf16374e07b4e7669b843c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 11:14:14 -0800 Subject: [PATCH 034/211] Add null checks to refresh line and character fetches Fixes #473 --- src/xterm.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/xterm.js b/src/xterm.js index b6c659c3..a46d0152 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1139,6 +1139,10 @@ Terminal.prototype.refresh = function(start, end) { row = y + this.ydisp; line = this.lines.get(row); + if (!line) { + // Continue if the line is not available, this means a resize is currently in progress + continue; + } out = ''; if (this.y === y - (this.ybase - this.ydisp) @@ -1153,6 +1157,10 @@ Terminal.prototype.refresh = function(start, end) { i = 0; for (; i < width; i++) { + if (!line[i]) { + // Continue if the character is not available, this means a resize is currently in progress + continue; + } data = line[i][0]; ch = line[i][1]; ch_width = line[i][2]; From 3de3912b96dce8ef1d900108cd64412ea19eb11a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 11:23:17 -0800 Subject: [PATCH 035/211] Add another null check on children[y] --- src/xterm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index a46d0152..b01421b1 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1139,7 +1139,7 @@ Terminal.prototype.refresh = function(start, end) { row = y + this.ydisp; line = this.lines.get(row); - if (!line) { + if (!line || !this.children[y]) { // Continue if the line is not available, this means a resize is currently in progress continue; } From f9a286a851dba75c8a77e4c12ca9bc5893a6e417 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 20:32:15 -0800 Subject: [PATCH 036/211] Convert more CSI codes --- src/InputHandler.ts | 209 ++++++++++++++++++++++++++++++++++++++++++++ src/Interfaces.ts | 47 +++++----- src/Parser.ts | 73 ++-------------- src/xterm.js | 202 ------------------------------------------ 4 files changed, 243 insertions(+), 288 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 51c6a2d9..8ecc075b 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -302,6 +302,215 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps L + * Insert Ps Line(s) (default = 1) (IL). + */ + public insertLines(params: number[]): void { + let param, row, j; + + param = params[0]; + if (param < 1) { + param = 1; + } + row = this._terminal.y + this._terminal.ybase; + + j = this._terminal.rows - 1 - this._terminal.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.ybase - j + 1; + + while (param--) { + if (this._terminal.lines.length === this._terminal.lines.maxLength) { + // Trim the start of lines to make room for the new line + this._terminal.lines.trimStart(1); + this._terminal.ybase--; + this._terminal.ydisp--; + row--; + j--; + } + // test: echo -e '\e[44m\e[1L\e[0m' + // blankLine(true) - xterm/linux behavior + this._terminal.lines.splice(row, 0, this._terminal.blankLine(true)); + this._terminal.lines.splice(j, 1); + } + + // this.maxRange(); + this._terminal.updateRange(this._terminal.y); + this._terminal.updateRange(this._terminal.scrollBottom); + } + + /** + * CSI Ps M + * Delete Ps Line(s) (default = 1) (DL). + */ + public deleteLines(params: number[]): void { + let param, row, j; + + param = params[0]; + if (param < 1) { + param = 1; + } + row = this._terminal.y + this._terminal.ybase; + + j = this._terminal.rows - 1 - this._terminal.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.ybase - j; + + while (param--) { + if (this._terminal.lines.length === this._terminal.lines.maxLength) { + // Trim the start of lines to make room for the new line + this._terminal.lines.trimStart(1); + this._terminal.ybase -= 1; + this._terminal.ydisp -= 1; + } + // test: echo -e '\e[44m\e[1M\e[0m' + // blankLine(true) - xterm/linux behavior + this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true)); + this._terminal.lines.splice(row, 1); + } + + // this.maxRange(); + this._terminal.updateRange(this._terminal.y); + this._terminal.updateRange(this._terminal.scrollBottom); + } + + /** + * CSI Ps P + * Delete Ps Character(s) (default = 1) (DCH). + */ + public deleteChars(params: number[]): void { + let param, row, ch; + + param = params[0]; + if (param < 1) { + param = 1; + } + + row = this._terminal.y + this._terminal.ybase; + ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm + + while (param--) { + this._terminal.lines.get(row).splice(this._terminal.x, 1); + this._terminal.lines.get(row).push(ch); + } + } + + /** + * CSI Ps X + * Erase Ps Character(s) (default = 1) (ECH). + */ + public eraseChars(params: number[]): void { + let param, row, j, ch; + + param = params[0]; + if (param < 1) { + param = 1; + } + + row = this._terminal.y + this._terminal.ybase; + j = this._terminal.x; + ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm + + while (param-- && j < this._terminal.cols) { + this._terminal.lines.get(row)[j++] = ch; + } + } + + /** + * CSI Pm ` Character Position Absolute + * [column] (default = [row,1]) (HPA). + */ + public charPosAbsolute(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x = param - 1; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + } + + /** + * CSI Pm a Character Position Relative + * [columns] (default = [row,col+1]) (HPR) + * reuse CSI Ps C ? + */ + public HPositionRelative(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x += param; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + } + + /** + * CSI Ps c Send Device Attributes (Primary DA). + * Ps = 0 or omitted -> request attributes from terminal. The + * response depends on the decTerminalID resource setting. + * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'') + * -> CSI ? 1 ; 0 c (``VT101 with No Options'') + * -> CSI ? 6 c (``VT102'') + * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'') + * The VT100-style response parameters do not mean anything by + * themselves. VT220 parameters do, telling the host what fea- + * tures the terminal supports: + * Ps = 1 -> 132-columns. + * Ps = 2 -> Printer. + * Ps = 6 -> Selective erase. + * Ps = 8 -> User-defined keys. + * Ps = 9 -> National replacement character sets. + * Ps = 1 5 -> Technical characters. + * Ps = 2 2 -> ANSI color, e.g., VT525. + * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode). + * CSI > Ps c + * Send Device Attributes (Secondary DA). + * Ps = 0 or omitted -> request the terminal's identification + * code. The response depends on the decTerminalID resource set- + * ting. It should apply only to VT220 and up, but xterm extends + * this to VT100. + * -> CSI > Pp ; Pv ; Pc c + * where Pp denotes the terminal type + * Pp = 0 -> ``VT100''. + * Pp = 1 -> ``VT220''. + * and Pv is the firmware version (for xterm, this was originally + * the XFree86 patch number, starting with 95). In a DEC termi- + * nal, Pc indicates the ROM cartridge registration number and is + * always zero. + * More information: + * xterm/charproc.c - line 2012, for more information. + * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?) + */ + public sendDeviceAttributes(params: number[]): void { + if (params[0] > 0) { + return; + } + + if (!this._terminal.prefix) { + if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) { + this._terminal.send(C0.ESC + '[?1;2c'); + } else if (this._terminal.is('linux')) { + this._terminal.send(C0.ESC + '[?6c'); + } + } else if (this._terminal.prefix === '>') { + // xterm and urxvt + // seem to spit this + // out around ~370 times (?). + if (this._terminal.is('xterm')) { + this._terminal.send(C0.ESC + '[>0;276;0c'); + } else if (this._terminal.is('rxvt-unicode')) { + this._terminal.send(C0.ESC + '[>85;95;0c'); + } else if (this._terminal.is('linux')) { + // not supported by linux console. + // linux console echoes parameters. + this._terminal.send(params[0] + 'c'); + } else if (this._terminal.is('screen')) { + this._terminal.send(C0.ESC + '[>83;40003;0c'); + } + } + } + /** * CSI Pm m Character Attributes (SGR). * Ps = 0 -> Normal (default). diff --git a/src/Interfaces.ts b/src/Interfaces.ts index a2cb71a6..e79fe502 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -37,24 +37,31 @@ export interface ITerminal { * Handles actions generated by the parser. */ export interface IInputHandler { - bell(): void; - lineFeed(): void; - carriageReturn(): void; - backspace(): void; - tab(): void; - shiftOut(): void; - shiftIn(): void; - insertChars(params); - cursorUp(params: number[]): void; - cursorDown(params: number[]): void; - cursorForward(params: number[]): void; - cursorBackward(params: number[]): void; - cursorNextLine(params: number[]): void; - cursorPrecedingLine(params: number[]): void; - cursorCharAbsolute(params: number[]): void; - cursorPosition(params: number[]): void; - eraseInDisplay(params: number[]): void; - eraseInLine(params: number[]): void; - charAttributes(params: number[]): void; - deviceStatus(params: number[]): void; + /** C0 BEL */ bell(): void; + /** C0 LF */ lineFeed(): void; + /** C0 CR */ carriageReturn(): void; + /** C0 BS */ backspace(): void; + /** C0 HT */ tab(): void; + /** C0 SO */ shiftOut(): void; + /** C0 SI */ shiftIn(): void; + /** CSI @ */ insertChars(params); + /** CSI A */ cursorUp(params: number[]): void; + /** CSI B */ cursorDown(params: number[]): void; + /** CSI C */ cursorForward(params: number[]): void; + /** CSI D */ cursorBackward(params: number[]): void; + /** CSI E */ cursorNextLine(params: number[]): void; + /** CSI F */ cursorPrecedingLine(params: number[]): void; + /** CSI G */ cursorCharAbsolute(params: number[]): void; + /** CSI H */ cursorPosition(params: number[]): void; + /** CSI J */ eraseInDisplay(params: number[]): void; + /** CSI K */ eraseInLine(params: number[]): void; + /** CSI L */ insertLines(params: number[]): void; + /** CSI M */ deleteLines(params: number[]): void; + /** CSI P */ deleteChars(params: number[]): void; + /** CSI X */ eraseChars(params: number[]): void; + /** CSI ` */ charPosAbsolute(params: number[]): void; + /** CSI a */ HPositionRelative(params: number[]): void; + /** CSI c */ sendDeviceAttributes(params: number[]): void; + /** CSI m */ charAttributes(params: number[]): void; + /** CSI n */ deviceStatus(params: number[]): void; } diff --git a/src/Parser.ts b/src/Parser.ts index 9a14bdfd..f438e6b0 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -46,6 +46,13 @@ csiStateHandler['G'] = (handler, params) => handler.cursorCharAbsolute(params); csiStateHandler['H'] = (handler, params) => handler.cursorPosition(params); csiStateHandler['J'] = (handler, params) => handler.eraseInDisplay(params); csiStateHandler['K'] = (handler, params) => handler.eraseInLine(params); +csiStateHandler['L'] = (handler, params) => handler.insertLines(params); +csiStateHandler['M'] = (handler, params) => handler.deleteLines(params); +csiStateHandler['P'] = (handler, params) => handler.deleteChars(params); +csiStateHandler['X'] = (handler, params) => handler.eraseChars(params); +csiStateHandler['`'] = (handler, params) => handler.charPosAbsolute(params); +csiStateHandler['a'] = (handler, params) => handler.HPositionRelative(params); +csiStateHandler['c'] = (handler, params) => handler.sendDeviceAttributes(params); csiStateHandler['m'] = (handler, params) => handler.charAttributes(params); csiStateHandler['n'] = (handler, params) => handler.deviceStatus(params); @@ -543,72 +550,6 @@ export class Parser { switch (ch) { - /** - * Additions - */ - - // CSI Ps E - // Cursor Next Line Ps Times (default = 1) (CNL). - case 'E': - this._terminal.cursorNextLine(this._terminal.params); - break; - - // CSI Ps F - // Cursor Preceding Line Ps Times (default = 1) (CNL). - case 'F': - this._terminal.cursorPrecedingLine(this._terminal.params); - break; - - // CSI Ps G - // Cursor Character Absolute [column] (default = [row,1]) (CHA). - case 'G': - this._terminal.cursorCharAbsolute(this._terminal.params); - break; - - // CSI Ps L - // Insert Ps Line(s) (default = 1) (IL). - case 'L': - this._terminal.insertLines(this._terminal.params); - break; - - // CSI Ps M - // Delete Ps Line(s) (default = 1) (DL). - case 'M': - this._terminal.deleteLines(this._terminal.params); - break; - - // CSI Ps P - // Delete Ps Character(s) (default = 1) (DCH). - case 'P': - this._terminal.deleteChars(this._terminal.params); - break; - - // CSI Ps X - // Erase Ps Character(s) (default = 1) (ECH). - case 'X': - this._terminal.eraseChars(this._terminal.params); - break; - - // CSI Pm ` Character Position Absolute - // [column] (default = [row,1]) (HPA). - case '`': - this._terminal.charPosAbsolute(this._terminal.params); - break; - - // 141 61 a * HPR - - // Horizontal Position Relative - case 'a': - this._terminal.HPositionRelative(this._terminal.params); - break; - - // CSI P s c - // Send Device Attributes (Primary DA). - // CSI > P s c - // Send Device Attributes (Secondary DA) - case 'c': - this._terminal.sendDeviceAttributes(this._terminal.params); - break; - // CSI Pm d // Line Position Absolute [row] (default = [1,column]) (VPA). case 'd': diff --git a/src/xterm.js b/src/xterm.js index 62baf517..c6246157 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2326,208 +2326,6 @@ Terminal.prototype.tabSet = function() { */ -/** - * CSI Ps L - * Insert Ps Line(s) (default = 1) (IL). - */ -Terminal.prototype.insertLines = function(params) { - var param, row, j; - - param = params[0]; - if (param < 1) param = 1; - row = this.y + this.ybase; - - j = this.rows - 1 - this.scrollBottom; - j = this.rows - 1 + this.ybase - j + 1; - - while (param--) { - if (this.lines.length === this.lines.maxLength) { - // Trim the start of lines to make room for the new line - this.lines.trimStart(1); - this.ybase--; - this.ydisp--; - row--; - j--; - } - // test: echo -e '\e[44m\e[1L\e[0m' - // blankLine(true) - xterm/linux behavior - this.lines.splice(row, 0, this.blankLine(true)); - this.lines.splice(j, 1); - } - - // this.maxRange(); - this.updateRange(this.y); - this.updateRange(this.scrollBottom); -}; - - -/** - * CSI Ps M - * Delete Ps Line(s) (default = 1) (DL). - */ -Terminal.prototype.deleteLines = function(params) { - var param, row, j; - - param = params[0]; - if (param < 1) param = 1; - row = this.y + this.ybase; - - j = this.rows - 1 - this.scrollBottom; - j = this.rows - 1 + this.ybase - j; - - while (param--) { - if (this.lines.length === this.lines.maxLength) { - // Trim the start of lines to make room for the new line - this.lines.trimStart(1); - this.ybase -= 1; - this.ydisp -= 1; - } - // test: echo -e '\e[44m\e[1M\e[0m' - // blankLine(true) - xterm/linux behavior - this.lines.splice(j + 1, 0, this.blankLine(true)); - this.lines.splice(row, 1); - } - - // this.maxRange(); - this.updateRange(this.y); - this.updateRange(this.scrollBottom); -}; - - -/** - * CSI Ps P - * Delete Ps Character(s) (default = 1) (DCH). - */ -Terminal.prototype.deleteChars = function(params) { - var param, row, ch; - - param = params[0]; - if (param < 1) param = 1; - - row = this.y + this.ybase; - ch = [this.eraseAttr(), ' ', 1]; // xterm - - while (param--) { - this.lines.get(row).splice(this.x, 1); - this.lines.get(row).push(ch); - } -}; - -/** - * CSI Ps X - * Erase Ps Character(s) (default = 1) (ECH). - */ -Terminal.prototype.eraseChars = function(params) { - var param, row, j, ch; - - param = params[0]; - if (param < 1) param = 1; - - row = this.y + this.ybase; - j = this.x; - ch = [this.eraseAttr(), ' ', 1]; // xterm - - while (param-- && j < this.cols) { - this.lines.get(row)[j++] = ch; - } -}; - -/** - * CSI Pm ` Character Position Absolute - * [column] (default = [row,1]) (HPA). - */ -Terminal.prototype.charPosAbsolute = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.x = param - 1; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; - - -/** - * 141 61 a * HPR - - * Horizontal Position Relative - * reuse CSI Ps C ? - */ -Terminal.prototype.HPositionRelative = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.x += param; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; - - -/** - * CSI Ps c Send Device Attributes (Primary DA). - * Ps = 0 or omitted -> request attributes from terminal. The - * response depends on the decTerminalID resource setting. - * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'') - * -> CSI ? 1 ; 0 c (``VT101 with No Options'') - * -> CSI ? 6 c (``VT102'') - * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'') - * The VT100-style response parameters do not mean anything by - * themselves. VT220 parameters do, telling the host what fea- - * tures the terminal supports: - * Ps = 1 -> 132-columns. - * Ps = 2 -> Printer. - * Ps = 6 -> Selective erase. - * Ps = 8 -> User-defined keys. - * Ps = 9 -> National replacement character sets. - * Ps = 1 5 -> Technical characters. - * Ps = 2 2 -> ANSI color, e.g., VT525. - * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode). - * CSI > Ps c - * Send Device Attributes (Secondary DA). - * Ps = 0 or omitted -> request the terminal's identification - * code. The response depends on the decTerminalID resource set- - * ting. It should apply only to VT220 and up, but xterm extends - * this to VT100. - * -> CSI > Pp ; Pv ; Pc c - * where Pp denotes the terminal type - * Pp = 0 -> ``VT100''. - * Pp = 1 -> ``VT220''. - * and Pv is the firmware version (for xterm, this was originally - * the XFree86 patch number, starting with 95). In a DEC termi- - * nal, Pc indicates the ROM cartridge registration number and is - * always zero. - * More information: - * xterm/charproc.c - line 2012, for more information. - * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?) - */ -Terminal.prototype.sendDeviceAttributes = function(params) { - if (params[0] > 0) return; - - if (!this.prefix) { - if (this.is('xterm') - || this.is('rxvt-unicode') - || this.is('screen')) { - this.send(C0.ESC + '[?1;2c'); - } else if (this.is('linux')) { - this.send(C0.ESC + '[?6c'); - } - } else if (this.prefix === '>') { - // xterm and urxvt - // seem to spit this - // out around ~370 times (?). - if (this.is('xterm')) { - this.send(C0.ESC + '[>0;276;0c'); - } else if (this.is('rxvt-unicode')) { - this.send(C0.ESC + '[>85;95;0c'); - } else if (this.is('linux')) { - // not supported by linux console. - // linux console echoes parameters. - this.send(params[0] + 'c'); - } else if (this.is('screen')) { - this.send(C0.ESC + '[>83;40003;0c'); - } - } -}; - - /** * CSI Pm d * Line Position Absolute [row] (default = [1,column]) (VPA). From c43c3b411ab1726a7e9de45af4a8422c612498cb Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 20:51:15 -0800 Subject: [PATCH 037/211] Add more CSI codes --- src/InputHandler.ts | 263 ++++++++++++++++++++++++++++++++++++++++++++ src/Interfaces.ts | 4 + src/Parser.ts | 28 +---- src/xterm.js | 259 ------------------------------------------- 4 files changed, 271 insertions(+), 283 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 8ecc075b..f54d7935 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1,5 +1,6 @@ import { IInputHandler, ITerminal } from './Interfaces'; import { C0 } from './EscapeSequences'; +import { CHARSETS } from './Charsets'; export class InputHandler implements IInputHandler { // TODO: We want to type _terminal when it's pulled into TS @@ -511,6 +512,268 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Pm d Vertical Position Absolute (VPA) + * [row] (default = [1,column]) + */ + public linePosAbsolute(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y = param - 1; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + } + + /** + * CSI Pm e Vertical Position Relative (VPR) + * [rows] (default = [row+1,column]) + * reuse CSI Ps B ? + */ + public VPositionRelative(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y += param; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + } + + /** + * CSI Ps ; Ps f + * Horizontal and Vertical Position [row;column] (default = + * [1,1]) (HVP). + */ + public HVPosition(params: number[]): void { + if (params[0] < 1) params[0] = 1; + if (params[1] < 1) params[1] = 1; + + this._terminal.y = params[0] - 1; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + + this._terminal.x = params[1] - 1; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + } + + + /** + * CSI Pm h Set Mode (SM). + * Ps = 2 -> Keyboard Action Mode (AM). + * Ps = 4 -> Insert Mode (IRM). + * Ps = 1 2 -> Send/receive (SRM). + * Ps = 2 0 -> Automatic Newline (LNM). + * CSI ? Pm h + * DEC Private Mode Set (DECSET). + * Ps = 1 -> Application Cursor Keys (DECCKM). + * Ps = 2 -> Designate USASCII for character sets G0-G3 + * (DECANM), and set VT100 mode. + * Ps = 3 -> 132 Column Mode (DECCOLM). + * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM). + * Ps = 5 -> Reverse Video (DECSCNM). + * Ps = 6 -> Origin Mode (DECOM). + * Ps = 7 -> Wraparound Mode (DECAWM). + * Ps = 8 -> Auto-repeat Keys (DECARM). + * Ps = 9 -> Send Mouse X & Y on button press. See the sec- + * tion Mouse Tracking. + * Ps = 1 0 -> Show toolbar (rxvt). + * Ps = 1 2 -> Start Blinking Cursor (att610). + * Ps = 1 8 -> Print form feed (DECPFF). + * Ps = 1 9 -> Set print extent to full screen (DECPEX). + * Ps = 2 5 -> Show Cursor (DECTCEM). + * Ps = 3 0 -> Show scrollbar (rxvt). + * Ps = 3 5 -> Enable font-shifting functions (rxvt). + * Ps = 3 8 -> Enter Tektronix Mode (DECTEK). + * Ps = 4 0 -> Allow 80 -> 132 Mode. + * Ps = 4 1 -> more(1) fix (see curses resource). + * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN- + * RCM). + * Ps = 4 4 -> Turn On Margin Bell. + * Ps = 4 5 -> Reverse-wraparound Mode. + * Ps = 4 6 -> Start Logging. This is normally disabled by a + * compile-time option. + * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis- + * abled by the titeInhibit resource). + * Ps = 6 6 -> Application keypad (DECNKM). + * Ps = 6 7 -> Backarrow key sends backspace (DECBKM). + * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and + * release. See the section Mouse Tracking. + * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking. + * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking. + * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking. + * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events. + * Ps = 1 0 0 5 -> Enable Extended Mouse Mode. + * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt). + * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt). + * Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit. + * (enables the eightBitInput resource). + * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num- + * Lock keys. (This enables the numLock resource). + * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This + * enables the metaSendsEscape resource). + * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete + * key. + * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This + * enables the altSendsEscape resource). + * Ps = 1 0 4 0 -> Keep selection even if not highlighted. + * (This enables the keepSelection resource). + * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables + * the selectToClipboard resource). + * Ps = 1 0 4 2 -> Enable Urgency window manager hint when + * Control-G is received. (This enables the bellIsUrgent + * resource). + * Ps = 1 0 4 3 -> Enable raising of the window when Control-G + * is received. (enables the popOnBell resource). + * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be + * disabled by the titeInhibit resource). + * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis- + * abled by the titeInhibit resource). + * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate + * Screen Buffer, clearing it first. (This may be disabled by + * the titeInhibit resource). This combines the effects of the 1 + * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based + * applications rather than the 4 7 mode. + * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode. + * Ps = 1 0 5 1 -> Set Sun function-key mode. + * Ps = 1 0 5 2 -> Set HP function-key mode. + * Ps = 1 0 5 3 -> Set SCO function-key mode. + * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6). + * Ps = 1 0 6 1 -> Set VT220 keyboard emulation. + * Ps = 2 0 0 4 -> Set bracketed paste mode. + * Modes: + * http: *vt100.net/docs/vt220-rm/chapter4.html + */ + public setMode(params: number[]): void { + if (params.length > 1) { + for (let i = 0; i < params.length; i++) { + this._terminal.setMode(params[i]); + } + + return; + } + + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = true; + break; + case 20: + // this._terminal.convertEol = true; + break; + } + } else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = true; + break; + case 2: + this._terminal.setgCharset(0, CHARSETS.US); + this._terminal.setgCharset(1, CHARSETS.US); + this._terminal.setgCharset(2, CHARSETS.US); + this._terminal.setgCharset(3, CHARSETS.US); + // set VT100 mode here + break; + case 3: // 132 col mode + this._terminal.savedCols = this._terminal.cols; + this._terminal.resize(132, this._terminal.rows); + break; + case 6: + this._terminal.originMode = true; + break; + case 7: + this._terminal.wraparoundMode = true; + break; + case 12: + // this.cursorBlink = true; + break; + case 66: + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + this._terminal.viewport.syncScrollArea(); + break; + case 9: // X10 Mouse + // no release, no motion, no wheel, no modifiers. + case 1000: // vt200 mouse + // no motion. + // no modifiers, except control on the wheel. + case 1002: // button event mouse + case 1003: // any event mouse + // any event - sends motion events, + // even if there is no button held down. + + // TODO: Why are params[0] compares nested within a switch for params[0]? + + this._terminal.x10Mouse = params[0] === 9; + this._terminal.vt200Mouse = params[0] === 1000; + this._terminal.normalMouse = params[0] > 1000; + this._terminal.mouseEvents = true; + this._terminal.element.style.cursor = 'default'; + this._terminal.log('Binding to mouse events.'); + break; + case 1004: // send focusin/focusout events + // focusin: ^[[I + // focusout: ^[[O + this._terminal.sendFocus = true; + break; + case 1005: // utf8 ext mode mouse + this._terminal.utfMouse = true; + // for wide terminals + // simply encodes large values as utf8 characters + break; + case 1006: // sgr ext mode mouse + this._terminal.sgrMouse = true; + // for wide terminals + // does not add 32 to fields + // press: ^[[ Normal (default). diff --git a/src/Interfaces.ts b/src/Interfaces.ts index e79fe502..f6b21233 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -62,6 +62,10 @@ export interface IInputHandler { /** CSI ` */ charPosAbsolute(params: number[]): void; /** CSI a */ HPositionRelative(params: number[]): void; /** CSI c */ sendDeviceAttributes(params: number[]): void; + /** CSI d */ linePosAbsolute(params: number[]): void; + /** CSI e */ VPositionRelative(params: number[]): void; + /** CSI f */ HVPosition(params: number[]): void; + /** CSI h */ setMode(params: number[]): void; /** CSI m */ charAttributes(params: number[]): void; /** CSI n */ deviceStatus(params: number[]): void; } diff --git a/src/Parser.ts b/src/Parser.ts index f438e6b0..4f5e7336 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -53,6 +53,10 @@ csiStateHandler['X'] = (handler, params) => handler.eraseChars(params); csiStateHandler['`'] = (handler, params) => handler.charPosAbsolute(params); csiStateHandler['a'] = (handler, params) => handler.HPositionRelative(params); csiStateHandler['c'] = (handler, params) => handler.sendDeviceAttributes(params); +csiStateHandler['d'] = (handler, params) => handler.linePosAbsolute(params); +csiStateHandler['e'] = (handler, params) => handler.VPositionRelative(params); +csiStateHandler['f'] = (handler, params) => handler.HVPosition(params); +csiStateHandler['h'] = (handler, params) => handler.setMode(params); csiStateHandler['m'] = (handler, params) => handler.charAttributes(params); csiStateHandler['n'] = (handler, params) => handler.deviceStatus(params); @@ -550,30 +554,6 @@ export class Parser { switch (ch) { - // CSI Pm d - // Line Position Absolute [row] (default = [1,column]) (VPA). - case 'd': - this._terminal.linePosAbsolute(this._terminal.params); - break; - - // 145 65 e * VPR - Vertical Position Relative - case 'e': - this._terminal.VPositionRelative(this._terminal.params); - break; - - // CSI Ps ; Ps f - // Horizontal and Vertical Position [row;column] (default = - // [1,1]) (HVP). - case 'f': - this._terminal.HVPosition(this._terminal.params); - break; - - // CSI Pm h Set Mode (SM). - // CSI ? Pm h - mouse escape codes, cursor escape codes - case 'h': - this._terminal.setMode(this._terminal.params); - break; - // CSI Pm l Reset Mode (RM). // CSI ? Pm l case 'l': diff --git a/src/xterm.js b/src/xterm.js index c6246157..3edd50aa 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2326,265 +2326,6 @@ Terminal.prototype.tabSet = function() { */ -/** - * CSI Pm d - * Line Position Absolute [row] (default = [1,column]) (VPA). - */ -Terminal.prototype.linePosAbsolute = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.y = param - 1; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } -}; - - -/** - * 145 65 e * VPR - Vertical Position Relative - * reuse CSI Ps B ? - */ -Terminal.prototype.VPositionRelative = function(params) { - var param = params[0]; - if (param < 1) param = 1; - this.y += param; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } -}; - - -/** - * CSI Ps ; Ps f - * Horizontal and Vertical Position [row;column] (default = - * [1,1]) (HVP). - */ -Terminal.prototype.HVPosition = function(params) { - if (params[0] < 1) params[0] = 1; - if (params[1] < 1) params[1] = 1; - - this.y = params[0] - 1; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } - - this.x = params[1] - 1; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; - - -/** - * CSI Pm h Set Mode (SM). - * Ps = 2 -> Keyboard Action Mode (AM). - * Ps = 4 -> Insert Mode (IRM). - * Ps = 1 2 -> Send/receive (SRM). - * Ps = 2 0 -> Automatic Newline (LNM). - * CSI ? Pm h - * DEC Private Mode Set (DECSET). - * Ps = 1 -> Application Cursor Keys (DECCKM). - * Ps = 2 -> Designate USASCII for character sets G0-G3 - * (DECANM), and set VT100 mode. - * Ps = 3 -> 132 Column Mode (DECCOLM). - * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM). - * Ps = 5 -> Reverse Video (DECSCNM). - * Ps = 6 -> Origin Mode (DECOM). - * Ps = 7 -> Wraparound Mode (DECAWM). - * Ps = 8 -> Auto-repeat Keys (DECARM). - * Ps = 9 -> Send Mouse X & Y on button press. See the sec- - * tion Mouse Tracking. - * Ps = 1 0 -> Show toolbar (rxvt). - * Ps = 1 2 -> Start Blinking Cursor (att610). - * Ps = 1 8 -> Print form feed (DECPFF). - * Ps = 1 9 -> Set print extent to full screen (DECPEX). - * Ps = 2 5 -> Show Cursor (DECTCEM). - * Ps = 3 0 -> Show scrollbar (rxvt). - * Ps = 3 5 -> Enable font-shifting functions (rxvt). - * Ps = 3 8 -> Enter Tektronix Mode (DECTEK). - * Ps = 4 0 -> Allow 80 -> 132 Mode. - * Ps = 4 1 -> more(1) fix (see curses resource). - * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN- - * RCM). - * Ps = 4 4 -> Turn On Margin Bell. - * Ps = 4 5 -> Reverse-wraparound Mode. - * Ps = 4 6 -> Start Logging. This is normally disabled by a - * compile-time option. - * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis- - * abled by the titeInhibit resource). - * Ps = 6 6 -> Application keypad (DECNKM). - * Ps = 6 7 -> Backarrow key sends backspace (DECBKM). - * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and - * release. See the section Mouse Tracking. - * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking. - * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking. - * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking. - * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events. - * Ps = 1 0 0 5 -> Enable Extended Mouse Mode. - * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt). - * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt). - * Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit. - * (enables the eightBitInput resource). - * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num- - * Lock keys. (This enables the numLock resource). - * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This - * enables the metaSendsEscape resource). - * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete - * key. - * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This - * enables the altSendsEscape resource). - * Ps = 1 0 4 0 -> Keep selection even if not highlighted. - * (This enables the keepSelection resource). - * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables - * the selectToClipboard resource). - * Ps = 1 0 4 2 -> Enable Urgency window manager hint when - * Control-G is received. (This enables the bellIsUrgent - * resource). - * Ps = 1 0 4 3 -> Enable raising of the window when Control-G - * is received. (enables the popOnBell resource). - * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be - * disabled by the titeInhibit resource). - * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis- - * abled by the titeInhibit resource). - * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate - * Screen Buffer, clearing it first. (This may be disabled by - * the titeInhibit resource). This combines the effects of the 1 - * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based - * applications rather than the 4 7 mode. - * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode. - * Ps = 1 0 5 1 -> Set Sun function-key mode. - * Ps = 1 0 5 2 -> Set HP function-key mode. - * Ps = 1 0 5 3 -> Set SCO function-key mode. - * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6). - * Ps = 1 0 6 1 -> Set VT220 keyboard emulation. - * Ps = 2 0 0 4 -> Set bracketed paste mode. - * Modes: - * http: *vt100.net/docs/vt220-rm/chapter4.html - */ -Terminal.prototype.setMode = function(params) { - if (typeof params === 'object') { - var l = params.length - , i = 0; - - for (; i < l; i++) { - this.setMode(params[i]); - } - - return; - } - - if (!this.prefix) { - switch (params) { - case 4: - this.insertMode = true; - break; - case 20: - //this.convertEol = true; - break; - } - } else if (this.prefix === '?') { - switch (params) { - case 1: - this.applicationCursor = true; - break; - case 2: - this.setgCharset(0, CHARSETS.US); - this.setgCharset(1, CHARSETS.US); - this.setgCharset(2, CHARSETS.US); - this.setgCharset(3, CHARSETS.US); - // set VT100 mode here - break; - case 3: // 132 col mode - this.savedCols = this.cols; - this.resize(132, this.rows); - break; - case 6: - this.originMode = true; - break; - case 7: - this.wraparoundMode = true; - break; - case 12: - // this.cursorBlink = true; - break; - case 66: - this.log('Serial port requested application keypad.'); - this.applicationKeypad = true; - this.viewport.syncScrollArea(); - break; - case 9: // X10 Mouse - // no release, no motion, no wheel, no modifiers. - case 1000: // vt200 mouse - // no motion. - // no modifiers, except control on the wheel. - case 1002: // button event mouse - case 1003: // any event mouse - // any event - sends motion events, - // even if there is no button held down. - this.x10Mouse = params === 9; - this.vt200Mouse = params === 1000; - this.normalMouse = params > 1000; - this.mouseEvents = true; - this.element.style.cursor = 'default'; - this.log('Binding to mouse events.'); - break; - case 1004: // send focusin/focusout events - // focusin: ^[[I - // focusout: ^[[O - this.sendFocus = true; - break; - case 1005: // utf8 ext mode mouse - this.utfMouse = true; - // for wide terminals - // simply encodes large values as utf8 characters - break; - case 1006: // sgr ext mode mouse - this.sgrMouse = true; - // for wide terminals - // does not add 32 to fields - // press: ^[[ Keyboard Action Mode (AM). From 9b66208029caadf9c292f8d9f705dcd4f24a069e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 21:33:28 -0800 Subject: [PATCH 038/211] Add more CSI codes --- src/InputHandler.ts | 221 +++++++++++++++++++++++++++++++++++++++++++ src/Interfaces.ts | 6 ++ src/Parser.ts | 36 +------ src/xterm.js | 226 -------------------------------------------- 4 files changed, 232 insertions(+), 257 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index f54d7935..98b85ba3 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -239,6 +239,17 @@ export class InputHandler implements IInputHandler { this._terminal.y = row; } + /** + * CSI Ps I + * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). + */ + public cursorForwardTab(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.x = this._terminal.nextStop(); + } + } + /** * CSI Ps J Erase in Display (ED). * Ps = 0 -> Erase Below (default). @@ -774,6 +785,183 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Pm l Reset Mode (RM). + * Ps = 2 -> Keyboard Action Mode (AM). + * Ps = 4 -> Replace Mode (IRM). + * Ps = 1 2 -> Send/receive (SRM). + * Ps = 2 0 -> Normal Linefeed (LNM). + * CSI ? Pm l + * DEC Private Mode Reset (DECRST). + * Ps = 1 -> Normal Cursor Keys (DECCKM). + * Ps = 2 -> Designate VT52 mode (DECANM). + * Ps = 3 -> 80 Column Mode (DECCOLM). + * Ps = 4 -> Jump (Fast) Scroll (DECSCLM). + * Ps = 5 -> Normal Video (DECSCNM). + * Ps = 6 -> Normal Cursor Mode (DECOM). + * Ps = 7 -> No Wraparound Mode (DECAWM). + * Ps = 8 -> No Auto-repeat Keys (DECARM). + * Ps = 9 -> Don't send Mouse X & Y on button press. + * Ps = 1 0 -> Hide toolbar (rxvt). + * Ps = 1 2 -> Stop Blinking Cursor (att610). + * Ps = 1 8 -> Don't print form feed (DECPFF). + * Ps = 1 9 -> Limit print to scrolling region (DECPEX). + * Ps = 2 5 -> Hide Cursor (DECTCEM). + * Ps = 3 0 -> Don't show scrollbar (rxvt). + * Ps = 3 5 -> Disable font-shifting functions (rxvt). + * Ps = 4 0 -> Disallow 80 -> 132 Mode. + * Ps = 4 1 -> No more(1) fix (see curses resource). + * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC- + * NRCM). + * Ps = 4 4 -> Turn Off Margin Bell. + * Ps = 4 5 -> No Reverse-wraparound Mode. + * Ps = 4 6 -> Stop Logging. (This is normally disabled by a + * compile-time option). + * Ps = 4 7 -> Use Normal Screen Buffer. + * Ps = 6 6 -> Numeric keypad (DECNKM). + * Ps = 6 7 -> Backarrow key sends delete (DECBKM). + * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and + * release. See the section Mouse Tracking. + * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking. + * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking. + * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking. + * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events. + * Ps = 1 0 0 5 -> Disable Extended Mouse Mode. + * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output + * (rxvt). + * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt). + * Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables + * the eightBitInput resource). + * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num- + * Lock keys. (This disables the numLock resource). + * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key. + * (This disables the metaSendsEscape resource). + * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad + * Delete key. + * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key. + * (This disables the altSendsEscape resource). + * Ps = 1 0 4 0 -> Do not keep selection when not highlighted. + * (This disables the keepSelection resource). + * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables + * the selectToClipboard resource). + * Ps = 1 0 4 2 -> Disable Urgency window manager hint when + * Control-G is received. (This disables the bellIsUrgent + * resource). + * Ps = 1 0 4 3 -> Disable raising of the window when Control- + * G is received. (This disables the popOnBell resource). + * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen + * first if in the Alternate Screen. (This may be disabled by + * the titeInhibit resource). + * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be + * disabled by the titeInhibit resource). + * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor + * as in DECRC. (This may be disabled by the titeInhibit + * resource). This combines the effects of the 1 0 4 7 and 1 0 + * 4 8 modes. Use this with terminfo-based applications rather + * than the 4 7 mode. + * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode. + * Ps = 1 0 5 1 -> Reset Sun function-key mode. + * Ps = 1 0 5 2 -> Reset HP function-key mode. + * Ps = 1 0 5 3 -> Reset SCO function-key mode. + * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6). + * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style. + * Ps = 2 0 0 4 -> Reset bracketed paste mode. + */ + public resetMode(params: number[]): void { + if (params.length > 1) { + for (let i = 0; i < params.length; i++) { + this._terminal.resetMode(params[i]); + } + + return; + } + + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = false; + break; + case 20: + // this._terminal.convertEol = false; + break; + } + } else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = false; + break; + case 3: + if (this._terminal.cols === 132 && this._terminal.savedCols) { + this._terminal.resize(this._terminal.savedCols, this._terminal.rows); + } + delete this._terminal.savedCols; + break; + case 6: + this._terminal.originMode = false; + break; + case 7: + this._terminal.wraparoundMode = false; + break; + case 12: + // this.cursorBlink = false; + break; + case 66: + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + break; + case 9: // X10 Mouse + case 1000: // vt200 mouse + case 1002: // button event mouse + case 1003: // any event mouse + this._terminal.x10Mouse = false; + this._terminal.vt200Mouse = false; + this._terminal.normalMouse = false; + this._terminal.mouseEvents = false; + this._terminal.element.style.cursor = ''; + break; + case 1004: // send focusin/focusout events + this._terminal.sendFocus = false; + break; + case 1005: // utf8 ext mode mouse + this._terminal.utfMouse = false; + break; + case 1006: // sgr ext mode mouse + this._terminal.sgrMouse = false; + break; + case 1015: // urxvt ext mode mouse + this._terminal.urxvtMouse = false; + break; + case 25: // hide cursor + this._terminal.cursorHidden = true; + break; + case 1049: // alt screen buffer cursor + ; // FALL-THROUGH + case 47: // normal screen buffer + case 1047: // normal screen buffer - clearing it first + if (this._terminal.normal) { + this._terminal.lines = this._terminal.normal.lines; + this._terminal.ybase = this._terminal.normal.ybase; + this._terminal.ydisp = this._terminal.normal.ydisp; + this._terminal.x = this._terminal.normal.x; + this._terminal.y = this._terminal.normal.y; + this._terminal.scrollTop = this._terminal.normal.scrollTop; + this._terminal.scrollBottom = this._terminal.normal.scrollBottom; + this._terminal.tabs = this._terminal.normal.tabs; + this._terminal.normal = null; + // if (params === 1049) { + // this.x = this.savedX; + // this.y = this.savedY; + // } + this._terminal.queueRefresh(0, this._terminal.rows - 1); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + } + break; + } + } + } + /** * CSI Pm m Character Attributes (SGR). * Ps = 0 -> Normal (default). @@ -1026,4 +1214,37 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps ; Ps r + * Set Scrolling Region [top;bottom] (default = full size of win- + * dow) (DECSTBM). + * CSI ? Pm r + */ + public setScrollRegion(params: number[]): void { + if (this._terminal.prefix) return; + this._terminal.scrollTop = (params[0] || 1) - 1; + this._terminal.scrollBottom = (params[1] || this._terminal.rows) - 1; + this._terminal.x = 0; + this._terminal.y = 0; + } + + + /** + * CSI s + * Save cursor (ANSI.SYS). + */ + public saveCursor(params: number[]): void { + this._terminal.savedX = this._terminal.x; + this._terminal.savedY = this._terminal.y; + } + + + /** + * CSI u + * Restore cursor (ANSI.SYS). + */ + public restoreCursor(params: number[]): void { + this._terminal.x = this._terminal.savedX || 0; + this._terminal.y = this._terminal.savedY || 0; + } } diff --git a/src/Interfaces.ts b/src/Interfaces.ts index f6b21233..b0f4464f 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -44,6 +44,7 @@ export interface IInputHandler { /** C0 HT */ tab(): void; /** C0 SO */ shiftOut(): void; /** C0 SI */ shiftIn(): void; + /** CSI @ */ insertChars(params); /** CSI A */ cursorUp(params: number[]): void; /** CSI B */ cursorDown(params: number[]): void; @@ -53,6 +54,7 @@ export interface IInputHandler { /** CSI F */ cursorPrecedingLine(params: number[]): void; /** CSI G */ cursorCharAbsolute(params: number[]): void; /** CSI H */ cursorPosition(params: number[]): void; + /** CSI I */ cursorForwardTab(params: number[]): void; /** CSI J */ eraseInDisplay(params: number[]): void; /** CSI K */ eraseInLine(params: number[]): void; /** CSI L */ insertLines(params: number[]): void; @@ -66,6 +68,10 @@ export interface IInputHandler { /** CSI e */ VPositionRelative(params: number[]): void; /** CSI f */ HVPosition(params: number[]): void; /** CSI h */ setMode(params: number[]): void; + /** CSI l */ resetMode(params: number[]): void; /** CSI m */ charAttributes(params: number[]): void; /** CSI n */ deviceStatus(params: number[]): void; + /** CSI r */ setScrollRegion(params: number[]): void; + /** CSI s */ saveCursor(params: number[]): void; + /** CSI u */ restoreCursor(params: number[]): void; } diff --git a/src/Parser.ts b/src/Parser.ts index 4f5e7336..89d19344 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -44,6 +44,7 @@ csiStateHandler['E'] = (handler, params) => handler.cursorNextLine(params); csiStateHandler['F'] = (handler, params) => handler.cursorPrecedingLine(params); csiStateHandler['G'] = (handler, params) => handler.cursorCharAbsolute(params); csiStateHandler['H'] = (handler, params) => handler.cursorPosition(params); +csiStateHandler['I'] = (handler, params) => handler.cursorForwardTab(params); csiStateHandler['J'] = (handler, params) => handler.eraseInDisplay(params); csiStateHandler['K'] = (handler, params) => handler.eraseInLine(params); csiStateHandler['L'] = (handler, params) => handler.insertLines(params); @@ -57,8 +58,12 @@ csiStateHandler['d'] = (handler, params) => handler.linePosAbsolute(params); csiStateHandler['e'] = (handler, params) => handler.VPositionRelative(params); csiStateHandler['f'] = (handler, params) => handler.HVPosition(params); csiStateHandler['h'] = (handler, params) => handler.setMode(params); +csiStateHandler['l'] = (handler, params) => handler.resetMode(params); csiStateHandler['m'] = (handler, params) => handler.charAttributes(params); csiStateHandler['n'] = (handler, params) => handler.deviceStatus(params); +csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); +csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); +csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); enum ParserState { NORMAL = 0, @@ -554,42 +559,11 @@ export class Parser { switch (ch) { - // CSI Pm l Reset Mode (RM). - // CSI ? Pm l - case 'l': - this._terminal.resetMode(this._terminal.params); - break; - - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - case 'r': - this._terminal.setScrollRegion(this._terminal.params); - break; - - // CSI s - // Save cursor (ANSI.SYS). - case 's': - this._terminal.saveCursor(this._terminal.params); - break; - - // CSI u - // Restore cursor (ANSI.SYS). - case 'u': - this._terminal.restoreCursor(this._terminal.params); - break; /** * Lesser Used */ - // CSI Ps I - // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). - case 'I': - this._terminal.cursorForwardTab(this._terminal.params); - break; - // CSI Ps S Scroll up Ps lines (default = 1) (SU). case 'S': this._terminal.scrollUp(this._terminal.params); diff --git a/src/xterm.js b/src/xterm.js index 3edd50aa..30cb7286 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2326,236 +2326,10 @@ Terminal.prototype.tabSet = function() { */ -/** - * CSI Pm l Reset Mode (RM). - * Ps = 2 -> Keyboard Action Mode (AM). - * Ps = 4 -> Replace Mode (IRM). - * Ps = 1 2 -> Send/receive (SRM). - * Ps = 2 0 -> Normal Linefeed (LNM). - * CSI ? Pm l - * DEC Private Mode Reset (DECRST). - * Ps = 1 -> Normal Cursor Keys (DECCKM). - * Ps = 2 -> Designate VT52 mode (DECANM). - * Ps = 3 -> 80 Column Mode (DECCOLM). - * Ps = 4 -> Jump (Fast) Scroll (DECSCLM). - * Ps = 5 -> Normal Video (DECSCNM). - * Ps = 6 -> Normal Cursor Mode (DECOM). - * Ps = 7 -> No Wraparound Mode (DECAWM). - * Ps = 8 -> No Auto-repeat Keys (DECARM). - * Ps = 9 -> Don't send Mouse X & Y on button press. - * Ps = 1 0 -> Hide toolbar (rxvt). - * Ps = 1 2 -> Stop Blinking Cursor (att610). - * Ps = 1 8 -> Don't print form feed (DECPFF). - * Ps = 1 9 -> Limit print to scrolling region (DECPEX). - * Ps = 2 5 -> Hide Cursor (DECTCEM). - * Ps = 3 0 -> Don't show scrollbar (rxvt). - * Ps = 3 5 -> Disable font-shifting functions (rxvt). - * Ps = 4 0 -> Disallow 80 -> 132 Mode. - * Ps = 4 1 -> No more(1) fix (see curses resource). - * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC- - * NRCM). - * Ps = 4 4 -> Turn Off Margin Bell. - * Ps = 4 5 -> No Reverse-wraparound Mode. - * Ps = 4 6 -> Stop Logging. (This is normally disabled by a - * compile-time option). - * Ps = 4 7 -> Use Normal Screen Buffer. - * Ps = 6 6 -> Numeric keypad (DECNKM). - * Ps = 6 7 -> Backarrow key sends delete (DECBKM). - * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and - * release. See the section Mouse Tracking. - * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking. - * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking. - * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking. - * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events. - * Ps = 1 0 0 5 -> Disable Extended Mouse Mode. - * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output - * (rxvt). - * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt). - * Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables - * the eightBitInput resource). - * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num- - * Lock keys. (This disables the numLock resource). - * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key. - * (This disables the metaSendsEscape resource). - * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad - * Delete key. - * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key. - * (This disables the altSendsEscape resource). - * Ps = 1 0 4 0 -> Do not keep selection when not highlighted. - * (This disables the keepSelection resource). - * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables - * the selectToClipboard resource). - * Ps = 1 0 4 2 -> Disable Urgency window manager hint when - * Control-G is received. (This disables the bellIsUrgent - * resource). - * Ps = 1 0 4 3 -> Disable raising of the window when Control- - * G is received. (This disables the popOnBell resource). - * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen - * first if in the Alternate Screen. (This may be disabled by - * the titeInhibit resource). - * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be - * disabled by the titeInhibit resource). - * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor - * as in DECRC. (This may be disabled by the titeInhibit - * resource). This combines the effects of the 1 0 4 7 and 1 0 - * 4 8 modes. Use this with terminfo-based applications rather - * than the 4 7 mode. - * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode. - * Ps = 1 0 5 1 -> Reset Sun function-key mode. - * Ps = 1 0 5 2 -> Reset HP function-key mode. - * Ps = 1 0 5 3 -> Reset SCO function-key mode. - * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6). - * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style. - * Ps = 2 0 0 4 -> Reset bracketed paste mode. - */ -Terminal.prototype.resetMode = function(params) { - if (typeof params === 'object') { - var l = params.length - , i = 0; - - for (; i < l; i++) { - this.resetMode(params[i]); - } - - return; - } - - if (!this.prefix) { - switch (params) { - case 4: - this.insertMode = false; - break; - case 20: - //this.convertEol = false; - break; - } - } else if (this.prefix === '?') { - switch (params) { - case 1: - this.applicationCursor = false; - break; - case 3: - if (this.cols === 132 && this.savedCols) { - this.resize(this.savedCols, this.rows); - } - delete this.savedCols; - break; - case 6: - this.originMode = false; - break; - case 7: - this.wraparoundMode = false; - break; - case 12: - // this.cursorBlink = false; - break; - case 66: - this.log('Switching back to normal keypad.'); - this.applicationKeypad = false; - this.viewport.syncScrollArea(); - break; - case 9: // X10 Mouse - case 1000: // vt200 mouse - case 1002: // button event mouse - case 1003: // any event mouse - this.x10Mouse = false; - this.vt200Mouse = false; - this.normalMouse = false; - this.mouseEvents = false; - this.element.style.cursor = ''; - break; - case 1004: // send focusin/focusout events - this.sendFocus = false; - break; - case 1005: // utf8 ext mode mouse - this.utfMouse = false; - break; - case 1006: // sgr ext mode mouse - this.sgrMouse = false; - break; - case 1015: // urxvt ext mode mouse - this.urxvtMouse = false; - break; - case 25: // hide cursor - this.cursorHidden = true; - break; - case 1049: // alt screen buffer cursor - ; // FALL-THROUGH - case 47: // normal screen buffer - case 1047: // normal screen buffer - clearing it first - if (this.normal) { - this.lines = this.normal.lines; - this.ybase = this.normal.ybase; - this.ydisp = this.normal.ydisp; - this.x = this.normal.x; - this.y = this.normal.y; - this.scrollTop = this.normal.scrollTop; - this.scrollBottom = this.normal.scrollBottom; - this.tabs = this.normal.tabs; - this.normal = null; - // if (params === 1049) { - // this.x = this.savedX; - // this.y = this.savedY; - // } - this.queueRefresh(0, this.rows - 1); - this.viewport.syncScrollArea(); - this.showCursor(); - } - break; - } - } -}; - - -/** - * CSI Ps ; Ps r - * Set Scrolling Region [top;bottom] (default = full size of win- - * dow) (DECSTBM). - * CSI ? Pm r - */ -Terminal.prototype.setScrollRegion = function(params) { - if (this.prefix) return; - this.scrollTop = (params[0] || 1) - 1; - this.scrollBottom = (params[1] || this.rows) - 1; - this.x = 0; - this.y = 0; -}; - - -/** - * CSI s - * Save cursor (ANSI.SYS). - */ -Terminal.prototype.saveCursor = function(params) { - this.savedX = this.x; - this.savedY = this.y; -}; - - -/** - * CSI u - * Restore cursor (ANSI.SYS). - */ -Terminal.prototype.restoreCursor = function(params) { - this.x = this.savedX || 0; - this.y = this.savedY || 0; -}; - - /** * Lesser Used */ -/** - * CSI Ps I - * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). - */ -Terminal.prototype.cursorForwardTab = function(params) { - var param = params[0] || 1; - while (param--) { - this.x = this.nextStop(); - } -}; /** From f4846aa1545834a7559f9085cec42c83971b4fa9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 21:58:50 -0800 Subject: [PATCH 039/211] Finish CSI codes --- src/InputHandler.ts | 88 +++++++++ src/Interfaces.ts | 64 +++--- src/Parser.ts | 324 +++++-------------------------- src/xterm.js | 464 -------------------------------------------- 4 files changed, 170 insertions(+), 770 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 98b85ba3..42c84769 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -405,6 +405,34 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps S Scroll up Ps lines (default = 1) (SU). + */ + public scrollUp(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1); + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine()); + } + // this.maxRange(); + this._terminal.updateRange(this._terminal.scrollTop); + this._terminal.updateRange(this._terminal.scrollBottom); + } + + /** + * CSI Ps T Scroll down Ps lines (default = 1) (SD). + */ + public scrollDown(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1); + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine()); + } + // this.maxRange(); + this._terminal.updateRange(this._terminal.scrollTop); + this._terminal.updateRange(this._terminal.scrollBottom); + } + /** * CSI Ps X * Erase Ps Character(s) (default = 1) (ECH). @@ -426,6 +454,16 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). + */ + public cursorBackwardTab(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.x = this._terminal.prevStop(); + } + } + /** * CSI Pm ` Character Position Absolute * [column] (default = [row,1]) (HPA). @@ -457,6 +495,19 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps b Repeat the preceding graphic character Ps times (REP). + */ + public repeatPrecedingCharacter(params: number[]): void { + let param = params[0] || 1 + , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y) + , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1]; + + while (param--) { + line[this._terminal.x++] = ch; + } + } + /** * CSI Ps c Send Device Attributes (Primary DA). * Ps = 0 or omitted -> request attributes from terminal. The @@ -574,6 +625,22 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI Ps g Tab Clear (TBC). + * Ps = 0 -> Clear Current Column (default). + * Ps = 3 -> Clear All. + * Potentially: + * Ps = 2 -> Clear Stops on Line. + * http://vt100.net/annarbor/aaa-ug/section6.html + */ + public tabClear(params: number[]): void { + let param = params[0]; + if (param <= 0) { + delete this._terminal.tabs[this._terminal.x]; + } else if (param === 3) { + this._terminal.tabs = {}; + } + } /** * CSI Pm h Set Mode (SM). @@ -1214,6 +1281,27 @@ export class InputHandler implements IInputHandler { } } + /** + * CSI ! p Soft terminal reset (DECSTR). + * http://vt100.net/docs/vt220-rm/table4-10.html + */ + public softReset(params: number[]): void { + this._terminal.cursorHidden = false; + this._terminal.insertMode = false; + this._terminal.originMode = false; + this._terminal.wraparoundMode = false; // autowrap + this._terminal.applicationKeypad = false; // ? + this._terminal.viewport.syncScrollArea(); + this._terminal.applicationCursor = false; + this._terminal.scrollTop = 0; + this._terminal.scrollBottom = this._terminal.rows - 1; + this._terminal.curAttr = this._terminal.defAttr; + this._terminal.x = this._terminal.y = 0; // ? + this._terminal.charset = null; + this._terminal.glevel = 0; // ?? + this._terminal.charsets = [null]; // ?? + } + /** * CSI Ps ; Ps r * Set Scrolling Region [top;bottom] (default = full size of win- diff --git a/src/Interfaces.ts b/src/Interfaces.ts index b0f4464f..0079b856 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -45,33 +45,39 @@ export interface IInputHandler { /** C0 SO */ shiftOut(): void; /** C0 SI */ shiftIn(): void; - /** CSI @ */ insertChars(params); - /** CSI A */ cursorUp(params: number[]): void; - /** CSI B */ cursorDown(params: number[]): void; - /** CSI C */ cursorForward(params: number[]): void; - /** CSI D */ cursorBackward(params: number[]): void; - /** CSI E */ cursorNextLine(params: number[]): void; - /** CSI F */ cursorPrecedingLine(params: number[]): void; - /** CSI G */ cursorCharAbsolute(params: number[]): void; - /** CSI H */ cursorPosition(params: number[]): void; - /** CSI I */ cursorForwardTab(params: number[]): void; - /** CSI J */ eraseInDisplay(params: number[]): void; - /** CSI K */ eraseInLine(params: number[]): void; - /** CSI L */ insertLines(params: number[]): void; - /** CSI M */ deleteLines(params: number[]): void; - /** CSI P */ deleteChars(params: number[]): void; - /** CSI X */ eraseChars(params: number[]): void; - /** CSI ` */ charPosAbsolute(params: number[]): void; - /** CSI a */ HPositionRelative(params: number[]): void; - /** CSI c */ sendDeviceAttributes(params: number[]): void; - /** CSI d */ linePosAbsolute(params: number[]): void; - /** CSI e */ VPositionRelative(params: number[]): void; - /** CSI f */ HVPosition(params: number[]): void; - /** CSI h */ setMode(params: number[]): void; - /** CSI l */ resetMode(params: number[]): void; - /** CSI m */ charAttributes(params: number[]): void; - /** CSI n */ deviceStatus(params: number[]): void; - /** CSI r */ setScrollRegion(params: number[]): void; - /** CSI s */ saveCursor(params: number[]): void; - /** CSI u */ restoreCursor(params: number[]): void; + /** CSI @ */ insertChars(params?: number[]): void; + /** CSI A */ cursorUp(params?: number[]): void; + /** CSI B */ cursorDown(params?: number[]): void; + /** CSI C */ cursorForward(params?: number[]): void; + /** CSI D */ cursorBackward(params?: number[]): void; + /** CSI E */ cursorNextLine(params?: number[]): void; + /** CSI F */ cursorPrecedingLine(params?: number[]): void; + /** CSI G */ cursorCharAbsolute(params?: number[]): void; + /** CSI H */ cursorPosition(params?: number[]): void; + /** CSI I */ cursorForwardTab(params?: number[]): void; + /** CSI J */ eraseInDisplay(params?: number[]): void; + /** CSI K */ eraseInLine(params?: number[]): void; + /** CSI L */ insertLines(params?: number[]): void; + /** CSI M */ deleteLines(params?: number[]): void; + /** CSI P */ deleteChars(params?: number[]): void; + /** CSI S */ scrollUp(params?: number[]): void; + /** CSI T */ scrollDown(params?: number[]): void; + /** CSI X */ eraseChars(params?: number[]): void; + /** CSI Z */ cursorBackwardTab(params?: number[]): void; + /** CSI ` */ charPosAbsolute(params?: number[]): void; + /** CSI a */ HPositionRelative(params?: number[]): void; + /** CSI b */ repeatPrecedingCharacter(params?: number[]): void; + /** CSI c */ sendDeviceAttributes(params?: number[]): void; + /** CSI d */ linePosAbsolute(params?: number[]): void; + /** CSI e */ VPositionRelative(params?: number[]): void; + /** CSI f */ HVPosition(params?: number[]): void; + /** CSI g */ tabClear(params?: number[]): void; + /** CSI h */ setMode(params?: number[]): void; + /** CSI l */ resetMode(params?: number[]): void; + /** CSI m */ charAttributes(params?: number[]): void; + /** CSI n */ deviceStatus(params?: number[]): void; + /** CSI p */ softReset(params?: number[]): void; + /** CSI r */ setScrollRegion(params?: number[]): void; + /** CSI s */ saveCursor(params?: number[]): void; + /** CSI u */ restoreCursor(params?: number[]): void; } diff --git a/src/Parser.ts b/src/Parser.ts index 89d19344..42554117 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -34,33 +34,47 @@ csiParamStateHandler[' '] = (parser) => parser.setPostfix(' '); csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); csiParamStateHandler[';'] = (parser) => parser.finalizeParam(); -const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[]) => void} = {}; -csiStateHandler['@'] = (handler, params) => handler.insertChars(params); -csiStateHandler['A'] = (handler, params) => handler.cursorUp(params); -csiStateHandler['B'] = (handler, params) => handler.cursorDown(params); -csiStateHandler['C'] = (handler, params) => handler.cursorForward(params); -csiStateHandler['D'] = (handler, params) => handler.cursorBackward(params); -csiStateHandler['E'] = (handler, params) => handler.cursorNextLine(params); -csiStateHandler['F'] = (handler, params) => handler.cursorPrecedingLine(params); -csiStateHandler['G'] = (handler, params) => handler.cursorCharAbsolute(params); -csiStateHandler['H'] = (handler, params) => handler.cursorPosition(params); -csiStateHandler['I'] = (handler, params) => handler.cursorForwardTab(params); -csiStateHandler['J'] = (handler, params) => handler.eraseInDisplay(params); -csiStateHandler['K'] = (handler, params) => handler.eraseInLine(params); -csiStateHandler['L'] = (handler, params) => handler.insertLines(params); -csiStateHandler['M'] = (handler, params) => handler.deleteLines(params); -csiStateHandler['P'] = (handler, params) => handler.deleteChars(params); -csiStateHandler['X'] = (handler, params) => handler.eraseChars(params); -csiStateHandler['`'] = (handler, params) => handler.charPosAbsolute(params); -csiStateHandler['a'] = (handler, params) => handler.HPositionRelative(params); -csiStateHandler['c'] = (handler, params) => handler.sendDeviceAttributes(params); -csiStateHandler['d'] = (handler, params) => handler.linePosAbsolute(params); -csiStateHandler['e'] = (handler, params) => handler.VPositionRelative(params); -csiStateHandler['f'] = (handler, params) => handler.HVPosition(params); -csiStateHandler['h'] = (handler, params) => handler.setMode(params); -csiStateHandler['l'] = (handler, params) => handler.resetMode(params); -csiStateHandler['m'] = (handler, params) => handler.charAttributes(params); -csiStateHandler['n'] = (handler, params) => handler.deviceStatus(params); +const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string) => void} = {}; +csiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params); +csiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params); +csiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params); +csiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params); +csiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params); +csiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params); +csiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params); +csiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params); +csiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params); +csiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params); +csiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params); +csiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params); +csiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params); +csiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params); +csiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params); +csiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params); +csiStateHandler['T'] = (handler, params, prefix) => { + if (params.length < 2 && !prefix) { + handler.scrollDown(params); + } +}; +csiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params); +csiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params); +csiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params); +csiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params); +csiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params); +csiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params); +csiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params); +csiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params); +csiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params); +csiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params); +csiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params); +csiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params); +csiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params); +csiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params); +csiStateHandler['p'] = (handler, params, prefix) => { + switch (prefix) { + case '!': handler.softReset(params); break; + } +}; csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); @@ -355,13 +369,13 @@ export class Parser { // ESC 7 Save Cursor (DECSC). case '7': - this._terminal.saveCursor(); + this._inputHandler.saveCursor(); this.state = ParserState.NORMAL; break; // ESC 8 Restore Cursor (DECRC). case '8': - this._terminal.restoreCursor(); + this._inputHandler.restoreCursor(); this.state = ParserState.NORMAL; break; @@ -549,257 +563,13 @@ export class Parser { this.state = ParserState.CSI; case ParserState.CSI: - this.state = ParserState.NORMAL; - if (ch in csiStateHandler) { - csiStateHandler[ch](this._inputHandler, this._terminal.params); - // Skip below switch as this has handled these codes (eventually everything will be handled here - break; - } - - switch (ch) { - - - /** - * Lesser Used - */ - - // CSI Ps S Scroll up Ps lines (default = 1) (SU). - case 'S': - this._terminal.scrollUp(this._terminal.params); - break; - - // CSI Ps T Scroll down Ps lines (default = 1) (SD). - // CSI Ps ; Ps ; Ps ; Ps ; Ps T - // CSI > Ps; Ps T - case 'T': - // if (this.prefix === '>') { - // this.resetTitleModes(this.params); - // break; - // } - // if (this.params.length > 2) { - // this.initMouseTracking(this.params); - // break; - // } - if (this._terminal.params.length < 2 && !this._terminal.prefix) { - this._terminal.scrollDown(this._terminal.params); - } - break; - - // CSI Ps Z - // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). - case 'Z': - this._terminal.cursorBackwardTab(this._terminal.params); - break; - - // CSI Ps b Repeat the preceding graphic character Ps times (REP). - case 'b': - this._terminal.repeatPrecedingCharacter(this._terminal.params); - break; - - // CSI Ps g Tab Clear (TBC). - case 'g': - this._terminal.tabClear(this._terminal.params); - break; - - // CSI Pm i Media Copy (MC). - // CSI ? Pm i - // case 'i': - // this.mediaCopy(this.params); - // break; - - // CSI Pm m Character Attributes (SGR). - // CSI > Ps; Ps m - // case 'm': // duplicate - // if (this.prefix === '>') { - // this.setResources(this.params); - // } else { - // this.charAttributes(this.params); - // } - // break; - - // CSI Ps n Device Status Report (DSR). - // CSI > Ps n - // case 'n': // duplicate - // if (this.prefix === '>') { - // this.disableModifiers(this.params); - // } else { - // this.deviceStatus(this.params); - // } - // break; - - // CSI > Ps p Set pointer mode. - // CSI ! p Soft terminal reset (DECSTR). - // CSI Ps$ p - // Request ANSI mode (DECRQM). - // CSI ? Ps$ p - // Request DEC private mode (DECRQM). - // CSI Ps ; Ps " p - case 'p': - switch (this._terminal.prefix) { - // case '>': - // this.setPointerMode(this.params); - // break; - case '!': - this._terminal.softReset(this._terminal.params); - break; - // case '?': - // if (this.postfix === '$') { - // this.requestPrivateMode(this.params); - // } - // break; - // default: - // if (this.postfix === '"') { - // this.setConformanceLevel(this.params); - // } else if (this.postfix === '$') { - // this.requestAnsiMode(this.params); - // } - // break; - } - break; - - // CSI Ps q Load LEDs (DECLL). - // CSI Ps SP q - // CSI Ps " q - // case 'q': - // if (this.postfix === ' ') { - // this.setCursorStyle(this.params); - // break; - // } - // if (this.postfix === '"') { - // this.setCharProtectionAttr(this.params); - // break; - // } - // this.loadLEDs(this.params); - // break; - - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - // CSI Pt; Pl; Pb; Pr; Ps$ r - // case 'r': // duplicate - // if (this.prefix === '?') { - // this.restorePrivateValues(this.params); - // } else if (this.postfix === '$') { - // this.setAttrInRectangle(this.params); - // } else { - // this.setScrollRegion(this.params); - // } - // break; - - // CSI s Save cursor (ANSI.SYS). - // CSI ? Pm s - // case 's': // duplicate - // if (this.prefix === '?') { - // this.savePrivateValues(this.params); - // } else { - // this.saveCursor(this.params); - // } - // break; - - // CSI Ps ; Ps ; Ps t - // CSI Pt; Pl; Pb; Pr; Ps$ t - // CSI > Ps; Ps t - // CSI Ps SP t - // case 't': - // if (this.postfix === '$') { - // this.reverseAttrInRectangle(this.params); - // } else if (this.postfix === ' ') { - // this.setWarningBellVolume(this.params); - // } else { - // if (this.prefix === '>') { - // this.setTitleModeFeature(this.params); - // } else { - // this.manipulateWindow(this.params); - // } - // } - // break; - - // CSI u Restore cursor (ANSI.SYS). - // CSI Ps SP u - // case 'u': // duplicate - // if (this.postfix === ' ') { - // this.setMarginBellVolume(this.params); - // } else { - // this.restoreCursor(this.params); - // } - // break; - - // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v - // case 'v': - // if (this.postfix === '$') { - // this.copyRectagle(this.params); - // } - // break; - - // CSI Pt ; Pl ; Pb ; Pr ' w - // case 'w': - // if (this.postfix === '\'') { - // this.enableFilterRectangle(this.params); - // } - // break; - - // CSI Ps x Request Terminal Parameters (DECREQTPARM). - // CSI Ps x Select Attribute Change Extent (DECSACE). - // CSI Pc; Pt; Pl; Pb; Pr$ x - // case 'x': - // if (this.postfix === '$') { - // this.fillRectangle(this.params); - // } else { - // this.requestParameters(this.params); - // //this.__(this.params); - // } - // break; - - // CSI Ps ; Pu ' z - // CSI Pt; Pl; Pb; Pr$ z - // case 'z': - // if (this.postfix === '\'') { - // this.enableLocatorReporting(this.params); - // } else if (this.postfix === '$') { - // this.eraseRectangle(this.params); - // } - // break; - - // CSI Pm ' { - // CSI Pt; Pl; Pb; Pr$ { - // case '{': - // if (this.postfix === '\'') { - // this.setLocatorEvents(this.params); - // } else if (this.postfix === '$') { - // this.selectiveEraseRectangle(this.params); - // } - // break; - - // CSI Ps ' | - // case '|': - // if (this.postfix === '\'') { - // this.requestLocatorPosition(this.params); - // } - // break; - - // CSI P m SP } - // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. - // case '}': - // if (this.postfix === ' ') { - // this.insertColumns(this.params); - // } - // break; - - // CSI P m SP ~ - // Delete P s Column(s) (default = 1) (DECDC), VT420 and up - // case '~': - // if (this.postfix === ' ') { - // this.deleteColumns(this.params); - // } - // break; - - default: - this._terminal.error('Unknown CSI code: %s.', ch); - break; + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix); + } else { + this._terminal.error('Unknown CSI code: %s.', ch); } + this.state = ParserState.NORMAL; this._terminal.prefix = ''; this._terminal.postfix = ''; break; diff --git a/src/xterm.js b/src/xterm.js index 30cb7286..b3ecdf8d 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2315,470 +2315,6 @@ Terminal.prototype.tabSet = function() { this.tabs[this.x] = true; }; - -/** - * CSI - */ - - -/** - * Additions - */ - - -/** - * Lesser Used - */ - - - -/** - * CSI Ps S Scroll up Ps lines (default = 1) (SU). - */ -Terminal.prototype.scrollUp = function(params) { - var param = params[0] || 1; - while (param--) { - this.lines.splice(this.ybase + this.scrollTop, 1); - this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine()); - } - // this.maxRange(); - this.updateRange(this.scrollTop); - this.updateRange(this.scrollBottom); -}; - - -/** - * CSI Ps T Scroll down Ps lines (default = 1) (SD). - */ -Terminal.prototype.scrollDown = function(params) { - var param = params[0] || 1; - while (param--) { - this.lines.splice(this.ybase + this.scrollBottom, 1); - this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine()); - } - // this.maxRange(); - this.updateRange(this.scrollTop); - this.updateRange(this.scrollBottom); -}; - - -/** - * CSI Ps ; Ps ; Ps ; Ps ; Ps T - * Initiate highlight mouse tracking. Parameters are - * [func;startx;starty;firstrow;lastrow]. See the section Mouse - * Tracking. - */ -Terminal.prototype.initMouseTracking = function(params) { - // Relevant: DECSET 1001 -}; - - -/** - * CSI > Ps; Ps T - * Reset one or more features of the title modes to the default - * value. Normally, "reset" disables the feature. It is possi- - * ble to disable the ability to reset features by compiling a - * different default for the title modes into xterm. - * Ps = 0 -> Do not set window/icon labels using hexadecimal. - * Ps = 1 -> Do not query window/icon labels using hexadeci- - * mal. - * Ps = 2 -> Do not set window/icon labels using UTF-8. - * Ps = 3 -> Do not query window/icon labels using UTF-8. - * (See discussion of "Title Modes"). - */ -Terminal.prototype.resetTitleModes = function(params) { - ; -}; - - -/** - * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). - */ -Terminal.prototype.cursorBackwardTab = function(params) { - var param = params[0] || 1; - while (param--) { - this.x = this.prevStop(); - } -}; - - -/** - * CSI Ps b Repeat the preceding graphic character Ps times (REP). - */ -Terminal.prototype.repeatPrecedingCharacter = function(params) { - var param = params[0] || 1 - , line = this.lines.get(this.ybase + this.y) - , ch = line[this.x - 1] || [this.defAttr, ' ', 1]; - - while (param--) line[this.x++] = ch; -}; - - -/** - * CSI Ps g Tab Clear (TBC). - * Ps = 0 -> Clear Current Column (default). - * Ps = 3 -> Clear All. - * Potentially: - * Ps = 2 -> Clear Stops on Line. - * http://vt100.net/annarbor/aaa-ug/section6.html - */ -Terminal.prototype.tabClear = function(params) { - var param = params[0]; - if (param <= 0) { - delete this.tabs[this.x]; - } else if (param === 3) { - this.tabs = {}; - } -}; - - -/** - * CSI Pm i Media Copy (MC). - * Ps = 0 -> Print screen (default). - * Ps = 4 -> Turn off printer controller mode. - * Ps = 5 -> Turn on printer controller mode. - * CSI ? Pm i - * Media Copy (MC, DEC-specific). - * Ps = 1 -> Print line containing cursor. - * Ps = 4 -> Turn off autoprint mode. - * Ps = 5 -> Turn on autoprint mode. - * Ps = 1 0 -> Print composed display, ignores DECPEX. - * Ps = 1 1 -> Print all pages. - */ -Terminal.prototype.mediaCopy = function(params) { - ; -}; - - -/** - * CSI > Ps; Ps m - * Set or reset resource-values used by xterm to decide whether - * to construct escape sequences holding information about the - * modifiers pressed with a given key. The first parameter iden- - * tifies the resource to set/reset. The second parameter is the - * value to assign to the resource. If the second parameter is - * omitted, the resource is reset to its initial value. - * Ps = 1 -> modifyCursorKeys. - * Ps = 2 -> modifyFunctionKeys. - * Ps = 4 -> modifyOtherKeys. - * If no parameters are given, all resources are reset to their - * initial values. - */ -Terminal.prototype.setResources = function(params) { - ; -}; - - -/** - * CSI > Ps n - * Disable modifiers which may be enabled via the CSI > Ps; Ps m - * sequence. This corresponds to a resource value of "-1", which - * cannot be set with the other sequence. The parameter identi- - * fies the resource to be disabled: - * Ps = 1 -> modifyCursorKeys. - * Ps = 2 -> modifyFunctionKeys. - * Ps = 4 -> modifyOtherKeys. - * If the parameter is omitted, modifyFunctionKeys is disabled. - * When modifyFunctionKeys is disabled, xterm uses the modifier - * keys to make an extended sequence of functions rather than - * adding a parameter to each function key to denote the modi- - * fiers. - */ -Terminal.prototype.disableModifiers = function(params) { - ; -}; - - -/** - * CSI > Ps p - * Set resource value pointerMode. This is used by xterm to - * decide whether to hide the pointer cursor as the user types. - * Valid values for the parameter: - * Ps = 0 -> never hide the pointer. - * Ps = 1 -> hide if the mouse tracking mode is not enabled. - * Ps = 2 -> always hide the pointer. If no parameter is - * given, xterm uses the default, which is 1 . - */ -Terminal.prototype.setPointerMode = function(params) { - ; -}; - - -/** - * CSI ! p Soft terminal reset (DECSTR). - * http://vt100.net/docs/vt220-rm/table4-10.html - */ -Terminal.prototype.softReset = function(params) { - this.cursorHidden = false; - this.insertMode = false; - this.originMode = false; - this.wraparoundMode = false; // autowrap - this.applicationKeypad = false; // ? - this.viewport.syncScrollArea(); - this.applicationCursor = false; - this.scrollTop = 0; - this.scrollBottom = this.rows - 1; - this.curAttr = this.defAttr; - this.x = this.y = 0; // ? - this.charset = null; - this.glevel = 0; // ?? - this.charsets = [null]; // ?? -}; - - -/** - * CSI Ps$ p - * Request ANSI mode (DECRQM). For VT300 and up, reply is - * CSI Ps; Pm$ y - * where Ps is the mode number as in RM, and Pm is the mode - * value: - * 0 - not recognized - * 1 - set - * 2 - reset - * 3 - permanently set - * 4 - permanently reset - */ -Terminal.prototype.requestAnsiMode = function(params) { - ; -}; - - -/** - * CSI ? Ps$ p - * Request DEC private mode (DECRQM). For VT300 and up, reply is - * CSI ? Ps; Pm$ p - * where Ps is the mode number as in DECSET, Pm is the mode value - * as in the ANSI DECRQM. - */ -Terminal.prototype.requestPrivateMode = function(params) { - ; -}; - - -/** - * CSI Ps ; Ps " p - * Set conformance level (DECSCL). Valid values for the first - * parameter: - * Ps = 6 1 -> VT100. - * Ps = 6 2 -> VT200. - * Ps = 6 3 -> VT300. - * Valid values for the second parameter: - * Ps = 0 -> 8-bit controls. - * Ps = 1 -> 7-bit controls (always set for VT100). - * Ps = 2 -> 8-bit controls. - */ -Terminal.prototype.setConformanceLevel = function(params) { - ; -}; - - -/** - * CSI Ps q Load LEDs (DECLL). - * Ps = 0 -> Clear all LEDS (default). - * Ps = 1 -> Light Num Lock. - * Ps = 2 -> Light Caps Lock. - * Ps = 3 -> Light Scroll Lock. - * Ps = 2 1 -> Extinguish Num Lock. - * Ps = 2 2 -> Extinguish Caps Lock. - * Ps = 2 3 -> Extinguish Scroll Lock. - */ -Terminal.prototype.loadLEDs = function(params) { - ; -}; - - -/** - * CSI Ps SP q - * Set cursor style (DECSCUSR, VT520). - * Ps = 0 -> blinking block. - * Ps = 1 -> blinking block (default). - * Ps = 2 -> steady block. - * Ps = 3 -> blinking underline. - * Ps = 4 -> steady underline. - */ -Terminal.prototype.setCursorStyle = function(params) { - ; -}; - - -/** - * CSI Ps " q - * Select character protection attribute (DECSCA). Valid values - * for the parameter: - * Ps = 0 -> DECSED and DECSEL can erase (default). - * Ps = 1 -> DECSED and DECSEL cannot erase. - * Ps = 2 -> DECSED and DECSEL can erase. - */ -Terminal.prototype.setCharProtectionAttr = function(params) { - ; -}; - - -/** - * CSI ? Pm r - * Restore DEC Private Mode Values. The value of Ps previously - * saved is restored. Ps values are the same as for DECSET. - */ -Terminal.prototype.restorePrivateValues = function(params) { - ; -}; - - -/** - * CSI Pt; Pl; Pb; Pr; Ps$ r - * Change Attributes in Rectangular Area (DECCARA), VT400 and up. - * Pt; Pl; Pb; Pr denotes the rectangle. - * Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.setAttrInRectangle = function(params) { - var t = params[0] - , l = params[1] - , b = params[2] - , r = params[3] - , attr = params[4]; - - var line - , i; - - for (; t < b + 1; t++) { - line = this.lines.get(this.ybase + t); - for (i = l; i < r; i++) { - line[i] = [attr, line[i][1]]; - } - } - - // this.maxRange(); - this.updateRange(params[0]); - this.updateRange(params[2]); -}; - - -/** - * CSI Pc; Pt; Pl; Pb; Pr$ x - * Fill Rectangular Area (DECFRA), VT420 and up. - * Pc is the character to use. - * Pt; Pl; Pb; Pr denotes the rectangle. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.fillRectangle = function(params) { - var ch = params[0] - , t = params[1] - , l = params[2] - , b = params[3] - , r = params[4]; - - var line - , i; - - for (; t < b + 1; t++) { - line = this.lines.get(this.ybase + t); - for (i = l; i < r; i++) { - line[i] = [line[i][0], String.fromCharCode(ch)]; - } - } - - // this.maxRange(); - this.updateRange(params[1]); - this.updateRange(params[3]); -}; - - -/** - * CSI Ps ; Pu ' z - * Enable Locator Reporting (DECELR). - * Valid values for the first parameter: - * Ps = 0 -> Locator disabled (default). - * Ps = 1 -> Locator enabled. - * Ps = 2 -> Locator enabled for one report, then disabled. - * The second parameter specifies the coordinate unit for locator - * reports. - * Valid values for the second parameter: - * Pu = 0 <- or omitted -> default to character cells. - * Pu = 1 <- device physical pixels. - * Pu = 2 <- character cells. - */ -Terminal.prototype.enableLocatorReporting = function(params) { - var val = params[0] > 0; - //this.mouseEvents = val; - //this.decLocator = val; -}; - - -/** - * CSI Pt; Pl; Pb; Pr$ z - * Erase Rectangular Area (DECERA), VT400 and up. - * Pt; Pl; Pb; Pr denotes the rectangle. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.eraseRectangle = function(params) { - var t = params[0] - , l = params[1] - , b = params[2] - , r = params[3]; - - var line - , i - , ch; - - ch = [this.eraseAttr(), ' ', 1]; // xterm? - - for (; t < b + 1; t++) { - line = this.lines.get(this.ybase + t); - for (i = l; i < r; i++) { - line[i] = ch; - } - } - - // this.maxRange(); - this.updateRange(params[0]); - this.updateRange(params[2]); -}; - - -/** - * CSI P m SP } - * Insert P s Column(s) (default = 1) (DECIC), VT420 and up. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.insertColumns = function() { - var param = params[0] - , l = this.ybase + this.rows - , ch = [this.eraseAttr(), ' ', 1] // xterm? - , i; - - while (param--) { - for (i = this.ybase; i < l; i++) { - this.lines.get(i).splice(this.x + 1, 0, ch); - this.lines.get(i).pop(); - } - } - - this.maxRange(); -}; - - -/** - * CSI P m SP ~ - * Delete P s Column(s) (default = 1) (DECDC), VT420 and up - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.deleteColumns = function() { - var param = params[0] - , l = this.ybase + this.rows - , ch = [this.eraseAttr(), ' ', 1] // xterm? - , i; - - while (param--) { - for (i = this.ybase; i < l; i++) { - this.lines.get(i).splice(this.x, 1); - this.lines.get(i).push(ch); - } - } - - this.maxRange(); -}; - /** * Helpers */ From fa3484cd14921a0b7dad46d764910cdfb59662bf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 22:17:36 -0800 Subject: [PATCH 040/211] Pull character add char code to input handler --- src/InputHandler.ts | 184 ++++++++++++++++++++++++++++++++++++ src/Interfaces.ts | 2 + src/Parser.ts | 225 ++++---------------------------------------- 3 files changed, 204 insertions(+), 207 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 42c84769..d13ad427 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -6,6 +6,85 @@ export class InputHandler implements IInputHandler { // TODO: We want to type _terminal when it's pulled into TS constructor(private _terminal: any) { } + public addChar(char: string, code: number): void { + if (char >= ' ') { + // calculate print space + // expensive call, therefore we save width in line buffer + const ch_width = wcwidth(code); + + if (this._terminal.charset && this._terminal.charset[char]) { + char = this._terminal.charset[char]; + } + + let row = this._terminal.y + this._terminal.ybase; + + // insert combining char in last cell + // FIXME: needs handling after cursor jumps + if (!ch_width && this._terminal.x) { + // dont overflow left + if (this._terminal.lines.get(row)[this._terminal.x - 1]) { + if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) { + + // found empty cell after fullwidth, need to go 2 cells back + if (this._terminal.lines.get(row)[this._terminal.x - 2]) + this._terminal.lines.get(row)[this._terminal.x - 2][1] += char; + + } else { + this._terminal.lines.get(row)[this._terminal.x - 1][1] += char; + } + this._terminal.updateRange(this._terminal.y); + } + return; + } + + // goto next line if ch would overflow + // TODO: needs a global min terminal width of 2 + if (this._terminal.x + ch_width - 1 >= this._terminal.cols) { + // autowrap - DECAWM + if (this._terminal.wraparoundMode) { + this._terminal.x = 0; + this._terminal.y++; + if (this._terminal.y > this._terminal.scrollBottom) { + this._terminal.y--; + this._terminal.scroll(); + } + } else { + this._terminal.x = this._terminal.cols - 1; + if (ch_width === 2) // FIXME: check for xterm behavior + return; + } + } + row = this._terminal.y + this._terminal.ybase; + + // insert mode: move characters to right + if (this._terminal.insertMode) { + // do this twice for a fullwidth char + for (let moves = 0; moves < ch_width; ++moves) { + // remove last cell, if it's width is 0 + // we have to adjust the second last cell as well + const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop(); + if (removed[2] === 0 + && this._terminal.lines.get(row)[this._terminal.cols - 2] + && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2) + this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1]; + + // insert empty cell at cursor + this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]); + } + } + + this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width]; + this._terminal.x++; + this._terminal.updateRange(this._terminal.y); + + // fullwidth char - set next cell width to zero and advance cursor + if (ch_width === 2) { + this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0]; + this._terminal.x++; + } + } + } + /** * BEL * Bell (Ctrl-G). @@ -1336,3 +1415,108 @@ export class InputHandler implements IInputHandler { this._terminal.y = this._terminal.savedY || 0; } } + +const wcwidth = (function(opts) { + // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c + // combining characters + const COMBINING = [ + [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], + [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], + [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], + [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], + [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], + [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], + [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], + [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], + [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], + [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], + [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], + [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], + [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], + [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], + [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], + [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], + [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], + [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], + [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], + [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], + [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], + [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], + [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], + [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], + [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], + [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], + [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], + [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], + [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], + [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], + [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], + [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], + [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], + [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], + [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], + [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], + [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], + [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], + [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], + [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], + [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], + [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], + [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], + [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], + [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], + [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], + [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], + [0xE0100, 0xE01EF] + ]; + // binary search + function bisearch(ucs) { + let min = 0; + let max = COMBINING.length - 1; + let mid; + if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1]) + return false; + while (max >= min) { + mid = Math.floor((min + max) / 2); + if (ucs > COMBINING[mid][1]) + min = mid + 1; + else if (ucs < COMBINING[mid][0]) + max = mid - 1; + else + return true; + } + return false; + } + function wcwidth(ucs) { + // test for 8-bit control characters + if (ucs === 0) + return opts.nul; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return opts.control; + // binary search in table of non-spacing characters + if (bisearch(ucs)) + return 0; + // if we arrive here, ucs is not a combining or C0/C1 control character + if (isWide(ucs)) { + return 2; + } + return 1; + } + function isWide(ucs) { + return ( + ucs >= 0x1100 && ( + ucs <= 0x115f || // Hangul Jamo init. consonants + ucs === 0x2329 || + ucs === 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi + (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables + (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs + (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms + (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms + (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); + } + return wcwidth; +})({nul: 0, control: 0}); // configurable options diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 0079b856..87809286 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -37,6 +37,8 @@ export interface ITerminal { * Handles actions generated by the parser. */ export interface IInputHandler { + addChar(char: string, code: number): void; + /** C0 BEL */ bell(): void; /** C0 LF */ lineFeed(): void; /** C0 CR */ carriageReturn(): void; diff --git a/src/Parser.ts b/src/Parser.ts index 42554117..95ecf754 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -2,17 +2,17 @@ import { C0 } from './EscapeSequences'; import { IInputHandler } from './Interfaces'; import { CHARSETS } from './Charsets'; -const normalStateHandler: {[key: string]: (handler: IInputHandler) => void} = {}; -normalStateHandler[C0.BEL] = (handler) => handler.bell(); -normalStateHandler[C0.LF] = (handler) => handler.lineFeed(); +const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {}; +normalStateHandler[C0.BEL] = (parser, handler) => handler.bell(); +normalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed(); normalStateHandler[C0.VT] = normalStateHandler[C0.LF]; normalStateHandler[C0.FF] = normalStateHandler[C0.LF]; -normalStateHandler[C0.CR] = (handler) => handler.carriageReturn(); -normalStateHandler[C0.BS] = (handler) => handler.backspace(); -normalStateHandler[C0.HT] = (handler) => handler.tab(); -normalStateHandler[C0.SO] = (handler) => handler.shiftOut(); -normalStateHandler[C0.SI] = (handler) => handler.shiftIn(); -// TODO: Add ESC and Default cases to normalStateHandler +normalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn(); +normalStateHandler[C0.BS] = (parser, handler) => handler.backspace(); +normalStateHandler[C0.HT] = (parser, handler) => handler.tab(); +normalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut(); +normalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn(); +normalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED); const csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {}; csiParamStateHandler['?'] = (parser) => parser.setPrefix('?'); @@ -102,7 +102,7 @@ export class Parser { } public parse(data: string) { - let l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; + let l = data.length, i = 0, j, cs, ch, code, low; // apply leftover surrogate high from last write if (this._terminal.surrogate_high) { @@ -132,100 +132,12 @@ export class Parser { if (0xDC00 <= code && code <= 0xDFFF) continue; - if (this.state === ParserState.NORMAL) { - if (ch in normalStateHandler) { - normalStateHandler[ch](this._inputHandler); - // Skip switch statement (eventually everything will be handled this way - continue; - } - } - switch (this.state) { case ParserState.NORMAL: - switch (ch) { - case C0.ESC: - this.state = ParserState.ESCAPED; - break; - - default: - // ' ' - // calculate print space - // expensive call, therefore we save width in line buffer - ch_width = wcwidth(code); - - if (ch >= ' ') { - if (this._terminal.charset && this._terminal.charset[ch]) { - ch = this._terminal.charset[ch]; - } - - row = this._terminal.y + this._terminal.ybase; - - // insert combining char in last cell - // FIXME: needs handling after cursor jumps - if (!ch_width && this._terminal.x) { - // dont overflow left - if (this._terminal.lines.get(row)[this._terminal.x - 1]) { - if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) { - - // found empty cell after fullwidth, need to go 2 cells back - if (this._terminal.lines.get(row)[this._terminal.x - 2]) - this._terminal.lines.get(row)[this._terminal.x - 2][1] += ch; - - } else { - this._terminal.lines.get(row)[this._terminal.x - 1][1] += ch; - } - this._terminal.updateRange(this._terminal.y); - } - break; - } - - // goto next line if ch would overflow - // TODO: needs a global min terminal width of 2 - if (this._terminal.x + ch_width - 1 >= this._terminal.cols) { - // autowrap - DECAWM - if (this._terminal.wraparoundMode) { - this._terminal.x = 0; - this._terminal.y++; - if (this._terminal.y > this._terminal.scrollBottom) { - this._terminal.y--; - this._terminal.scroll(); - } - } else { - this._terminal.x = this._terminal.cols - 1; - if (ch_width === 2) // FIXME: check for xterm behavior - continue; - } - } - row = this._terminal.y + this._terminal.ybase; - - // insert mode: move characters to right - if (this._terminal.insertMode) { - // do this twice for a fullwidth char - for (let moves = 0; moves < ch_width; ++moves) { - // remove last cell, if it's width is 0 - // we have to adjust the second last cell as well - const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop(); - if (removed[2] === 0 - && this._terminal.lines.get(row)[this._terminal.cols - 2] - && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2) - this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1]; - - // insert empty cell at cursor - this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]); - } - } - - this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, ch, ch_width]; - this._terminal.x++; - this._terminal.updateRange(this._terminal.y); - - // fullwidth char - set next cell width to zero and advance cursor - if (ch_width === 2) { - this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0]; - this._terminal.x++; - } - } - break; + if (ch in normalStateHandler) { + normalStateHandler[ch](this, this._inputHandler); + } else { + this._inputHandler.addChar(ch, code); } break; case ParserState.ESCAPED: @@ -671,6 +583,10 @@ export class Parser { } } + public setState(state: ParserState): void { + this.state = state; + } + public setPrefix(prefix: string): void { this._terminal.prefix = prefix; } @@ -692,108 +608,3 @@ export class Parser { this._terminal.postfix = postfix; } } - -const wcwidth = (function(opts) { - // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c - // combining characters - const COMBINING = [ - [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], - [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], - [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], - [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], - [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], - [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], - [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], - [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], - [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], - [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], - [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], - [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], - [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], - [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], - [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], - [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], - [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], - [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], - [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], - [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], - [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], - [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], - [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], - [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], - [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], - [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], - [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], - [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], - [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], - [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], - [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], - [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], - [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], - [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], - [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], - [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], - [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], - [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], - [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], - [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], - [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], - [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], - [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], - [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], - [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], - [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], - [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], - [0xE0100, 0xE01EF] - ]; - // binary search - function bisearch(ucs) { - let min = 0; - let max = COMBINING.length - 1; - let mid; - if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1]) - return false; - while (max >= min) { - mid = Math.floor((min + max) / 2); - if (ucs > COMBINING[mid][1]) - min = mid + 1; - else if (ucs < COMBINING[mid][0]) - max = mid - 1; - else - return true; - } - return false; - } - function wcwidth(ucs) { - // test for 8-bit control characters - if (ucs === 0) - return opts.nul; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return opts.control; - // binary search in table of non-spacing characters - if (bisearch(ucs)) - return 0; - // if we arrive here, ucs is not a combining or C0/C1 control character - if (isWide(ucs)) { - return 2; - } - return 1; - } - function isWide(ucs) { - return ( - ucs >= 0x1100 && ( - ucs <= 0x115f || // Hangul Jamo init. consonants - ucs === 0x2329 || - ucs === 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi - (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables - (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs - (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms - (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms - (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); - } - return wcwidth; -})({nul: 0, control: 0}); // configurable options From ecd7e69f1a0be3c0e072112344d33d96ad8f5027 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Jan 2017 22:36:48 -0800 Subject: [PATCH 041/211] Start adding ESC state handler --- src/Parser.ts | 195 ++++++++++++++++++++++++++------------------------ 1 file changed, 103 insertions(+), 92 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 95ecf754..5dab9cef 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -14,6 +14,63 @@ normalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut(); normalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn(); normalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED); +// TODO: Remove terminal when parser owns params and currentParam +const escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {}; +escapedStateHandler['['] = (parser, terminal) => { + // ESC [ Control Sequence Introducer (CSI is 0x9b) + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.CSI_PARAM); +}; +escapedStateHandler[']'] = (parser, terminal) => { + // ESC ] Operating System Command (OSC is 0x9d) + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.OSC); +}; +escapedStateHandler['P'] = (parser, terminal) => { + // ESC P Device Control String (DCS is 0x90) + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.DCS); +}; +escapedStateHandler['_'] = (parser, terminal) => { + // ESC _ Application Program Command ( APC is 0x9f). + parser.setState(ParserState.IGNORE); +} +escapedStateHandler['^'] = (parser, terminal) => { + // ESC ^ Privacy Message ( PM is 0x9e). + parser.setState(ParserState.IGNORE); +} +escapedStateHandler['c'] = (parser, terminal) => { + // ESC c Full Reset (RIS). + terminal.reset(); +} +escapedStateHandler['E'] = (parser, terminal) => { + // ESC E Next Line ( NEL is 0x85). + terminal.x = 0; + terminal.index(); + parser.setState(ParserState.NORMAL); +} +escapedStateHandler['D'] = (parser, terminal) => { + // ESC D Index ( IND is 0x84). + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['M'] = (parser, terminal) => { + // ESC M Reverse Index ( RI is 0x8d). + terminal.reverseIndex(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['%'] = (parser, terminal) => { + // ESC % Select default/utf-8 character set. + // @ = default, G = utf-8 + terminal.setgLevel(0); + terminal.setgCharset(0, CHARSETS.US); + parser.setState(ParserState.NORMAL); + parser.skipNextChar(); +}; + const csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {}; csiParamStateHandler['?'] = (parser) => parser.setPrefix('?'); csiParamStateHandler['>'] = (parser) => parser.setPrefix('>'); @@ -91,48 +148,50 @@ enum ParserState { } export class Parser { - private state: ParserState; + private _state: ParserState; + private _position: number; // TODO: Remove terminal when handler can do everything constructor( private _inputHandler: IInputHandler, private _terminal: any ) { - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; } public parse(data: string) { - let l = data.length, i = 0, j, cs, ch, code, low; + let l = data.length, j, cs, ch, code, low; + this._position = 0; // apply leftover surrogate high from last write if (this._terminal.surrogate_high) { data = this._terminal.surrogate_high + data; this._terminal.surrogate_high = ''; } - for (; i < l; i++) { - ch = data[i]; + for (; this._position < l; this._position++) { + ch = data[this._position]; // FIXME: higher chars than 0xa0 are not allowed in escape sequences // --> maybe move to default - code = data.charCodeAt(i); + code = data.charCodeAt(this._position); if (0xD800 <= code && code <= 0xDBFF) { // we got a surrogate high // get surrogate low (next 2 bytes) - low = data.charCodeAt(i + 1); + low = data.charCodeAt(this._position + 1); if (isNaN(low)) { // end of data stream, save surrogate high this._terminal.surrogate_high = ch; continue; } code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; - ch += data.charAt(i + 1); + ch += data.charAt(this._position + 1); } // surrogate low - already handled above if (0xDC00 <= code && code <= 0xDFFF) continue; - switch (this.state) { + switch (this._state) { case ParserState.NORMAL: if (ch in normalStateHandler) { normalStateHandler[ch](this, this._inputHandler); @@ -141,68 +200,12 @@ export class Parser { } break; case ParserState.ESCAPED: + if (ch in escapedStateHandler) { + escapedStateHandler[ch](this, this._terminal); + // Skip switch as it was just handled + break; + } switch (ch) { - // ESC [ Control Sequence Introducer ( CSI is 0x9b). - case '[': - this._terminal.params = []; - this._terminal.currentParam = 0; - this.state = ParserState.CSI_PARAM; - break; - - // ESC ] Operating System Command ( OSC is 0x9d). - case ']': - this._terminal.params = []; - this._terminal.currentParam = 0; - this.state = ParserState.OSC; - break; - - // ESC P Device Control String ( DCS is 0x90). - case 'P': - this._terminal.params = []; - this._terminal.currentParam = 0; - this.state = ParserState.DCS; - break; - - // ESC _ Application Program Command ( APC is 0x9f). - case '_': - this.state = ParserState.IGNORE; - break; - - // ESC ^ Privacy Message ( PM is 0x9e). - case '^': - this.state = ParserState.IGNORE; - break; - - // ESC c Full Reset (RIS). - case 'c': - this._terminal.reset(); - break; - - // ESC E Next Line ( NEL is 0x85). - // ESC D Index ( IND is 0x84). - case 'E': - this._terminal.x = 0; - ; - case 'D': - this._terminal.index(); - this.state = ParserState.NORMAL; - break; - - // ESC M Reverse Index ( RI is 0x8d). - case 'M': - this._terminal.reverseIndex(); - this.state = ParserState.NORMAL; - break; - - // ESC % Select default/utf-8 character set. - // @ = default, G = utf-8 - case '%': - // this.charset = null; - this._terminal.setgLevel(0); - this._terminal.setgCharset(0, CHARSETS.US); - this.state = ParserState.NORMAL; - i++; - break; // ESC (,),*,+,-,. Designate G0-G2 Character Set. case '(': // <-- this seems to get all the attention @@ -231,7 +234,7 @@ export class Parser { this._terminal.gcharset = 2; break; } - this.state = ParserState.CHARSET; + this._state = ParserState.CHARSET; break; // Designate G3 Character Set (VT300). @@ -239,8 +242,8 @@ export class Parser { // Not implemented. case '/': this._terminal.gcharset = 3; - this.state = ParserState.CHARSET; - i--; + this._state = ParserState.CHARSET; + this._position--; break; // ESC N @@ -282,25 +285,25 @@ export class Parser { // ESC 7 Save Cursor (DECSC). case '7': this._inputHandler.saveCursor(); - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; break; // ESC 8 Restore Cursor (DECRC). case '8': this._inputHandler.restoreCursor(); - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; break; // ESC # 3 DEC line height/width case '#': - this.state = ParserState.NORMAL; - i++; + this._state = ParserState.NORMAL; + this._position++; break; // ESC H Tab Set (HTS is 0x88). case 'H': this._terminal.tabSet(); - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; break; // ESC = Application Keypad (DECKPAM). @@ -308,7 +311,7 @@ export class Parser { this._terminal.log('Serial port requested application keypad.'); this._terminal.applicationKeypad = true; this._terminal.viewport.syncScrollArea(); - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; break; // ESC > Normal Keypad (DECKPNM). @@ -316,11 +319,11 @@ export class Parser { this._terminal.log('Switching back to normal keypad.'); this._terminal.applicationKeypad = false; this._terminal.viewport.syncScrollArea(); - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; break; default: - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; this._terminal.error('Unknown ESC control: %s.', ch); break; } @@ -372,7 +375,7 @@ export class Parser { break; case '/': // ISOLatin (actually /A) cs = CHARSETS.ISOLatin; - i++; + this._position++; break; default: // Default cs = CHARSETS.US; @@ -380,7 +383,7 @@ export class Parser { } this._terminal.setgCharset(this._terminal.gcharset, cs); this._terminal.gcharset = null; - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; break; case ParserState.OSC: @@ -388,7 +391,7 @@ export class Parser { // OSC Ps ; Pt BEL // Set Text Parameters. if (ch === C0.ESC || ch === C0.BEL) { - if (ch === C0.ESC) i++; + if (ch === C0.ESC) this._position++; this._terminal.params.push(this._terminal.currentParam); @@ -449,7 +452,7 @@ export class Parser { this._terminal.params = []; this._terminal.currentParam = 0; - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; } else { if (!this._terminal.params.length) { if (ch >= '0' && ch <= '9') { @@ -472,7 +475,7 @@ export class Parser { } this.finalizeParam(); // Fall through the CSI as this character should be the CSI code. - this.state = ParserState.CSI; + this._state = ParserState.CSI; case ParserState.CSI: if (ch in csiStateHandler) { @@ -481,14 +484,14 @@ export class Parser { this._terminal.error('Unknown CSI code: %s.', ch); } - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; this._terminal.prefix = ''; this._terminal.postfix = ''; break; case ParserState.DCS: if (ch === C0.ESC || ch === C0.BEL) { - if (ch === C0.ESC) i++; + if (ch === C0.ESC) this._position++; switch (this._terminal.prefix) { // User-Defined Keys (DECUDK). @@ -558,7 +561,7 @@ export class Parser { this._terminal.currentParam = 0; this._terminal.prefix = ''; - this.state = ParserState.NORMAL; + this._state = ParserState.NORMAL; } else if (!this._terminal.currentParam) { if (!this._terminal.prefix && ch !== '$' && ch !== '+') { this._terminal.currentParam = ch; @@ -575,8 +578,8 @@ export class Parser { case ParserState.IGNORE: // For PM and APC. if (ch === C0.ESC || ch === C0.BEL) { - if (ch === C0.ESC) i++; - this.state = ParserState.NORMAL; + if (ch === C0.ESC) this._position++; + this._state = ParserState.NORMAL; } break; } @@ -584,7 +587,7 @@ export class Parser { } public setState(state: ParserState): void { - this.state = state; + this._state = state; } public setPrefix(prefix: string): void { @@ -607,4 +610,12 @@ export class Parser { public setPostfix(postfix: string): void { this._terminal.postfix = postfix; } + + public skipNextChar(): void { + this._position++; + } + + // public repeatChar(): void { + // this._position--; + // } } From 5a932b2a20db211cc687776d4431e60ffc083c05 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 13 Jan 2017 21:27:19 -0800 Subject: [PATCH 042/211] Apply scrollback via setOption Fixes #476 --- demo/index.html | 7 ++++++- demo/main.js | 10 +++++++--- src/xterm.js | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/demo/index.html b/demo/index.html index 285fe002..764c8442 100644 --- a/demo/index.html +++ b/demo/index.html @@ -16,7 +16,12 @@

Options

- +

+ +

+

+ +

Size

diff --git a/demo/main.js b/demo/main.js index 86fbd314..52da2cef 100644 --- a/demo/main.js +++ b/demo/main.js @@ -8,7 +8,8 @@ var term, var terminalContainer = document.getElementById('terminal-container'), optionElements = { - cursorBlink: document.querySelector('#option-cursor-blink') + cursorBlink: document.querySelector('#option-cursor-blink'), + scrollback: document.querySelector('#option-scrollback') }, colsElement = document.getElementById('cols'), rowsElement = document.getElementById('rows'); @@ -28,6 +29,9 @@ colsElement.addEventListener('change', setTerminalSize); rowsElement.addEventListener('change', setTerminalSize); optionElements.cursorBlink.addEventListener('change', createTerminal); +optionElements.scrollback.addEventListener('change', function () { + terminal.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); +}); createTerminal(); @@ -37,7 +41,8 @@ function createTerminal() { terminalContainer.removeChild(terminalContainer.children[0]); } term = new Terminal({ - cursorBlink: optionElements.cursorBlink.checked + cursorBlink: optionElements.cursorBlink.checked, + scrollback: parseInt(optionElements.scrollback.value, 10) }); term.on('resize', function (size) { if (!pid) { @@ -78,7 +83,6 @@ function createTerminal() { }); } - function runRealTerminal() { term.attach(socket); term._initialized = true; diff --git a/src/xterm.js b/src/xterm.js index b6c659c3..5881e131 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -405,6 +405,24 @@ Terminal.prototype.setOption = function(key, value) { if (!(key in Terminal.defaults)) { throw new Error('No option with key "' + key + '"'); } + switch (key) { + case 'scrollback': + if (this.options[key] !== value) { + if (this.lines.length > value) { + const amountToTrim = this.lines.length - value; + const needsRefresh = (this.ydisp - amountToTrim < 0); + this.lines.trimStart(amountToTrim); + this.ybase = Math.max(this.ybase - amountToTrim, 0); + this.ydisp = Math.max(this.ydisp - amountToTrim, 0); + if (needsRefresh) { + this.refresh(0, this.rows - 1); + } + } + this.lines.maxLength = value; + this.viewport.syncScrollArea(); + } + break; + } this[key] = value; this.options[key] = value; }; From 7679475bfe0452446bb8eadaaa09dbe7e7d65b88 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 13 Jan 2017 21:31:31 -0800 Subject: [PATCH 043/211] Apply cursorBlink via setOption Fixes #478 --- demo/main.js | 4 +++- src/xterm.js | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/demo/main.js b/demo/main.js index 86fbd314..7425c051 100644 --- a/demo/main.js +++ b/demo/main.js @@ -27,7 +27,9 @@ function setTerminalSize () { colsElement.addEventListener('change', setTerminalSize); rowsElement.addEventListener('change', setTerminalSize); -optionElements.cursorBlink.addEventListener('change', createTerminal); +optionElements.cursorBlink.addEventListener('change', function () { + term.setOption('cursorBlink', optionElements.cursorBlink.checked); +}); createTerminal(); diff --git a/src/xterm.js b/src/xterm.js index b6c659c3..482d69a1 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -407,6 +407,9 @@ Terminal.prototype.setOption = function(key, value) { } this[key] = value; this.options[key] = value; + switch (key) { + case 'cursorBlink': this.refresh(this.y, this.y); break; + } }; /** From ac6faf3dd892314ee56ee416219ba8620c41e544 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Sat, 14 Jan 2017 19:52:07 +0200 Subject: [PATCH 044/211] Stick gulp-sourcemaps to 1.9.1 Paths became absolute by default at https://github.com/floridoo/gulp-sourcemaps/commit/fb4027a496898b8b7992ea5af9b3d707f1d82d38 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5071a70..2a043a85 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "glob": "^7.0.5", "gulp": "^3.9.1", "gulp-cli": "^1.2.2", - "gulp-sourcemaps": "^1.9.1", + "gulp-sourcemaps": "1.9.1", "gulp-typescript": "^3.1.3", "jsdoc": "3.4.3", "merge-stream": "^1.0.1", From d1dac57f7af5017b4b96696dc8722480fac2905e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 14 Jan 2017 21:26:49 -0800 Subject: [PATCH 045/211] Move cursor blink style to class on .terminal --- src/xterm.css | 6 +++--- src/xterm.js | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index 3f4f4bbe..4ef61fdf 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -82,11 +82,11 @@ background-color: transparent; } -.terminal.focus .terminal-cursor.blinking { - animation: blink-cursor 1.2s infinite step-end; +.terminal.focus.xterm-cursor-blink .terminal-cursor { + animation: cursor-blink 1.2s infinite step-end; } -@keyframes blink-cursor { +@keyframes cursor-blink { 0% { background-color: #fff; color: #000; diff --git a/src/xterm.js b/src/xterm.js index 482d69a1..a62033dd 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -408,7 +408,7 @@ Terminal.prototype.setOption = function(key, value) { this[key] = value; this.options[key] = value; switch (key) { - case 'cursorBlink': this.refresh(this.y, this.y); break; + case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break; } }; @@ -566,6 +566,7 @@ Terminal.prototype.open = function(parent) { this.element.classList.add('terminal'); this.element.classList.add('xterm'); this.element.classList.add('xterm-theme-' + this.theme); + this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink); this.element.style.height this.element.setAttribute('tabindex', 0); @@ -1170,11 +1171,7 @@ Terminal.prototype.refresh = function(start, end) { } if (data !== this.defAttr) { if (data === -1) { - out += ''; + out += ''; } else { var classNames = []; From 4448ebe391744381dbac0fa7a4045ad99813ef1e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 14 Jan 2017 22:06:30 -0800 Subject: [PATCH 046/211] Use charsets to map --- src/Parser.ts | 87 +++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 5dab9cef..b429c570 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -37,21 +37,21 @@ escapedStateHandler['P'] = (parser, terminal) => { escapedStateHandler['_'] = (parser, terminal) => { // ESC _ Application Program Command ( APC is 0x9f). parser.setState(ParserState.IGNORE); -} +}; escapedStateHandler['^'] = (parser, terminal) => { // ESC ^ Privacy Message ( PM is 0x9e). parser.setState(ParserState.IGNORE); -} +}; escapedStateHandler['c'] = (parser, terminal) => { // ESC c Full Reset (RIS). terminal.reset(); -} +}; escapedStateHandler['E'] = (parser, terminal) => { // ESC E Next Line ( NEL is 0x85). terminal.x = 0; terminal.index(); parser.setState(ParserState.NORMAL); -} +}; escapedStateHandler['D'] = (parser, terminal) => { // ESC D Index ( IND is 0x84). terminal.index(); @@ -136,6 +136,28 @@ csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); +// TODO: Many codes/charsets appear to not be supported +// See: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html +const charsetMap = { + '0': CHARSETS.SCLD, + 'A': CHARSETS.UK, // United Kingdom + 'B': CHARSETS.US, // United States (USASCII) + '4': CHARSETS.Dutch, + 'C': CHARSETS.Finnish, + '5': CHARSETS.Finnish, + 'f': CHARSETS.French, + 'Q': CHARSETS.FrenchCanadian, + 'K': CHARSETS.German, + 'Y': CHARSETS.Italian, + 'E': CHARSETS.NorwegianDanish, + '6': CHARSETS.NorwegianDanish, + 'Z': CHARSETS.Spanish, + 'H': CHARSETS.Swedish, + '7': CHARSETS.Swedish, + '=': CHARSETS.Swiss, + '/': CHARSETS.ISOLatin // ISOLatin is actually /A +}; + enum ParserState { NORMAL = 0, ESCAPED = 1, @@ -330,56 +352,13 @@ export class Parser { break; case ParserState.CHARSET: - switch (ch) { - case '0': // DEC Special Character and Line Drawing Set. - cs = CHARSETS.SCLD; - break; - case 'A': // UK - cs = CHARSETS.UK; - break; - case 'B': // United States (USASCII). - cs = CHARSETS.US; - break; - case '4': // Dutch - cs = CHARSETS.Dutch; - break; - case 'C': // Finnish - case '5': - cs = CHARSETS.Finnish; - break; - case 'R': // French - cs = CHARSETS.French; - break; - case 'Q': // FrenchCanadian - cs = CHARSETS.FrenchCanadian; - break; - case 'K': // German - cs = CHARSETS.German; - break; - case 'Y': // Italian - cs = CHARSETS.Italian; - break; - case 'E': // NorwegianDanish - case '6': - cs = CHARSETS.NorwegianDanish; - break; - case 'Z': // Spanish - cs = CHARSETS.Spanish; - break; - case 'H': // Swedish - case '7': - cs = CHARSETS.Swedish; - break; - case '=': // Swiss - cs = CHARSETS.Swiss; - break; - case '/': // ISOLatin (actually /A) - cs = CHARSETS.ISOLatin; - this._position++; - break; - default: // Default - cs = CHARSETS.US; - break; + if (ch in charsetMap) { + cs = charsetMap[ch]; + if (ch === '/') { // ISOLatin is actually /A + this.skipNextChar(); + } + } else { + cs = CHARSETS.US; // Default } this._terminal.setgCharset(this._terminal.gcharset, cs); this._terminal.gcharset = null; From 12160a50cbd7b9c46485fa69fc75cf53d2458aff Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 15 Jan 2017 02:27:34 -0800 Subject: [PATCH 047/211] Fake xterm.element in tests --- src/test/test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/test.js b/src/test/test.js index 7c716b2a..4f9342e5 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -23,6 +23,11 @@ describe('xterm.js', function() { xterm.writeBuffer.push(data); xterm.innerWrite(); }; + xterm.element = { + classList: { + toggle: function(){} + } + }; }); describe('getOption', function() { From a05bb5023043b08f0d4508a634f1527e6e653d7f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 15 Jan 2017 21:41:42 -0800 Subject: [PATCH 048/211] Don't drop selection on modifier keyup Fixes #348 --- src/xterm.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 6649a033..ed415b31 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -525,7 +525,11 @@ Terminal.bindKeys = function(term) { term.keyPress(ev); }, true); - on(term.element, 'keyup', term.focus.bind(term)); + on(term.element, 'keyup', function(ev) { + if (!wasMondifierKeyOnlyEvent(ev)) { + term.focus(term); + } + }, true); on(term.textarea, 'keydown', function(ev) { term.keyDown(ev); @@ -4984,6 +4988,12 @@ Terminal.prototype.deleteColumns = function() { this.maxRange(); }; +function wasMondifierKeyOnlyEvent(ev) { + return ev.keyCode === 16 || // Shift + ev.keyCode === 17 || // Ctrl + ev.keyCode === 18; // Alt +} + /** * Character Sets */ From 94eb08fb73acf12a7b06da6ee29e6228a0fe0fac Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 16 Jan 2017 14:02:55 -0800 Subject: [PATCH 049/211] Remove comments in build --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index f5a7d66c..c9e7fd46 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,8 @@ "rootDir": "src", "allowJs": true, "outDir": "lib", - "sourceMap": true + "sourceMap": true, + "removeComments": true }, "include": [ "src/**/*" From 1cdd2e00ab70180126dfa1c813c62bd0a895e047 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 16 Jan 2017 14:11:00 -0800 Subject: [PATCH 050/211] Remove parser states from xterm.js --- src/xterm.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 40de418a..24a840c0 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -37,11 +37,6 @@ import { CHARSETS } from './Charsets'; // Let it work inside Node.js for automated testing purposes. var document = (typeof window != 'undefined') ? window.document : null; -/** - * States - */ -var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6; - /** * The amount of write requests to queue before sending an XOFF signal to the * pty process. This number must be small in order for ^C and similar sequences From a4080d37063891080e729ef96ed5ae60db205b0e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 18 Jan 2017 08:06:24 -0800 Subject: [PATCH 051/211] Namespace cursor-blink CSS animations Fixes #489 --- src/xterm.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index 4ef61fdf..623164a2 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -83,10 +83,10 @@ } .terminal.focus.xterm-cursor-blink .terminal-cursor { - animation: cursor-blink 1.2s infinite step-end; + animation: xterm-cursor-blink 1.2s infinite step-end; } -@keyframes cursor-blink { +@keyframes xterm-cursor-blink { 0% { background-color: #fff; color: #000; From ef60e50e1decaaf79ca0fb1f988f1a1c5aa0c1b7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 18 Jan 2017 09:35:27 -0800 Subject: [PATCH 052/211] Add documentation --- src/Charsets.ts | 11 ++++++++- src/InputHandler.ts | 11 +++++++++ src/Parser.ts | 58 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/Charsets.ts b/src/Charsets.ts index 4035d453..3220f7d5 100644 --- a/src/Charsets.ts +++ b/src/Charsets.ts @@ -1,4 +1,13 @@ -// TODO: Give this a proper type +/** + * @license MIT + */ + +// TODO: Give CHARSETS a proper type +/** + * The character sets supported by the terminal. These enable several languages + * to be represented within the terminal with only 8-bit encoding. See ISO 2022 + * for a discussion on character sets. + */ export const CHARSETS: any = {}; // DEC Special Character and Line Drawing Set. diff --git a/src/InputHandler.ts b/src/InputHandler.ts index d13ad427..00626ceb 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1,7 +1,18 @@ +/** + * @license MIT + */ + import { IInputHandler, ITerminal } from './Interfaces'; import { C0 } from './EscapeSequences'; import { CHARSETS } from './Charsets'; +/** + * The terminal's standard implementation of IInputHandler, this handles all + * input from the Parser. + * + * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand + * each function's header comment. + */ export class InputHandler implements IInputHandler { // TODO: We want to type _terminal when it's pulled into TS constructor(private _terminal: any) { } diff --git a/src/Parser.ts b/src/Parser.ts index b429c570..860baaa6 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1,3 +1,7 @@ +/** + * @license MIT + */ + import { C0 } from './EscapeSequences'; import { IInputHandler } from './Interfaces'; import { CHARSETS } from './Charsets'; @@ -169,6 +173,11 @@ enum ParserState { IGNORE = 7 } +/** + * The terminal's parser, all input into the terminal goes through the parser + * which parses and defers the actual input handling the the IInputHandler + * specified in the constructor. + */ export class Parser { private _state: ParserState; private _position: number; @@ -181,6 +190,11 @@ export class Parser { this._state = ParserState.NORMAL; } + /** + * Parse and handle data. + * + * @param data The data to parse. + */ public parse(data: string) { let l = data.length, j, cs, ch, code, low; @@ -565,35 +579,71 @@ export class Parser { } } + /** + * Set the parser's current parsing state. + * + * @param state The new state. + */ public setState(state: ParserState): void { this._state = state; } + /** + * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>' + * or '!'. + * + * @param prefix The prefix. + */ public setPrefix(prefix: string): void { this._terminal.prefix = prefix; } + /** + * Sets the parsier's current prefix. CSI codes can have postfixes of '$', + * '"', ' ', '\''. + * + * @param postfix The postfix. + */ + public setPostfix(postfix: string): void { + this._terminal.postfix = postfix; + } + + /** + * Sets the parser's current parameter. + * + * @param param the parameter. + */ public setParam(param: number) { this._terminal.currentParam = param; } + /** + * Gets the parser's current parameter. + */ public getParam(): number { return this._terminal.currentParam; } + /** + * Finalizes the parser's current parameter, adding it to the list of + * parameters and setting the new current parameter to 0. + */ public finalizeParam(): void { this._terminal.params.push(this._terminal.currentParam); this._terminal.currentParam = 0; } - public setPostfix(postfix: string): void { - this._terminal.postfix = postfix; - } - + /** + * Tell the parser to skip the next character. + */ public skipNextChar(): void { this._position++; } + /** + * Tell the parser to repeat parsing the current character (for example if it + * needs parsing using a different state. + */ // public repeatChar(): void { // this._position--; // } From 0bd469f505d9dec1447fdf82c8e7772e0451fe7e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 16 Jan 2017 14:53:35 -0800 Subject: [PATCH 053/211] Implement CSI Ps SP q Set cursor style Fixes #480 --- demo/style.css | 4 ---- src/InputHandler.ts | 30 ++++++++++++++++++++++++++++++ src/Interfaces.ts | 1 + src/Parser.ts | 9 +++++++-- src/xterm.css | 36 ++++++++++++++++++++++++++++++++++-- src/xterm.js | 6 ++++++ 6 files changed, 78 insertions(+), 8 deletions(-) diff --git a/demo/style.css b/demo/style.css index 2f05e309..71389621 100644 --- a/demo/style.css +++ b/demo/style.css @@ -20,7 +20,3 @@ h1 { color: #fafafa; padding: 2px; } - -#terminal-container .terminal:focus .terminal-cursor { - background-color: #fafafa; -} diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 00626ceb..975d7c11 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1392,6 +1392,36 @@ export class InputHandler implements IInputHandler { this._terminal.charsets = [null]; // ?? } + /** + * CSI Ps SP q Set cursor style (DECSCUSR, VT520). + * Ps = 0 -> blinking block. + * Ps = 1 -> blinking block (default). + * Ps = 2 -> steady block. + * Ps = 3 -> blinking underline. + * Ps = 4 -> steady underline. + * Ps = 5 -> blinking bar (xterm). + * Ps = 6 -> steady bar (xterm). + */ + public setCursorStyle(params?: number[]): void { + const param = params[0] < 1 ? 1 : params[0]; + switch (param) { + case 1: + case 2: + this._terminal.setOption('cursorStyle', 'block'); + break; + case 3: + case 4: + this._terminal.setOption('cursorStyle', 'underline'); + break; + case 5: + case 6: + this._terminal.setOption('cursorStyle', 'bar'); + break; + } + const isBlinking = param % 2 === 1; + this._terminal.setOption('cursorBlink', isBlinking); + } + /** * CSI Ps ; Ps r * Set Scrolling Region [top;bottom] (default = full size of win- diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 87809286..049a599c 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -79,6 +79,7 @@ export interface IInputHandler { /** CSI m */ charAttributes(params?: number[]): void; /** CSI n */ deviceStatus(params?: number[]): void; /** CSI p */ softReset(params?: number[]): void; + /** CSI q */ setCursorStyle(params?: number[]): void; /** CSI r */ setScrollRegion(params?: number[]): void; /** CSI s */ saveCursor(params?: number[]): void; /** CSI u */ restoreCursor(params?: number[]): void; diff --git a/src/Parser.ts b/src/Parser.ts index 860baaa6..02028005 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -95,7 +95,7 @@ csiParamStateHandler[' '] = (parser) => parser.setPostfix(' '); csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); csiParamStateHandler[';'] = (parser) => parser.finalizeParam(); -const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string) => void} = {}; +const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string) => void} = {}; csiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params); csiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params); csiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params); @@ -136,6 +136,11 @@ csiStateHandler['p'] = (handler, params, prefix) => { case '!': handler.softReset(params); break; } }; +csiStateHandler['q'] = (handler, params, prefix, postfix) => { + if (postfix === ' ') { + handler.setCursorStyle(params); + } +}; csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); @@ -472,7 +477,7 @@ export class Parser { case ParserState.CSI: if (ch in csiStateHandler) { - csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix); + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix); } else { this._terminal.error('Unknown CSI code: %s.', ch); } diff --git a/src/xterm.css b/src/xterm.css index 623164a2..27638e14 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -71,7 +71,7 @@ resize: none; } -.terminal .terminal-cursor { +.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { background-color: #fff; color: #000; } @@ -82,7 +82,7 @@ background-color: transparent; } -.terminal.focus.xterm-cursor-blink .terminal-cursor { +.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink .terminal-cursor { animation: xterm-cursor-blink 1.2s infinite step-end; } @@ -97,6 +97,38 @@ } } +.terminal.xterm-cursor-style-bar .terminal-cursor, +.terminal.xterm-cursor-style-underline .terminal-cursor { + position: relative; +} +.terminal.xterm-cursor-style-bar .terminal-cursor::before, +.terminal.xterm-cursor-style-underline .terminal-cursor::before { + content: ""; + display: block; + position: absolute; + background-color: #fff; +} +.terminal.xterm-cursor-style-bar .terminal-cursor::before { + top: 0; + bottom: 0; + left: 0; + width: 1px; +} +.terminal.xterm-cursor-style-underline .terminal-cursor::before { + bottom: 0; + left: 0; + right: 0; + height: 1px; +} +.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before, +.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before { + animation: xterm-cursor-non-bar-blink 1.2s infinite step-end; +} +@keyframes xterm-cursor-non-bar-blink { + 0% { background-color: #fff; } + 50% { background-color: transparent; } +} + .terminal .composition-view { background: #000; color: #FFF; diff --git a/src/xterm.js b/src/xterm.js index 24a840c0..7f50295f 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -353,6 +353,7 @@ Terminal.defaults = { termName: 'xterm', geometry: [80, 24], cursorBlink: false, + cursorStyle: 'block', visualBell: false, popOnBell: false, scrollback: 1000, @@ -427,6 +428,11 @@ Terminal.prototype.setOption = function(key, value) { this.options[key] = value; switch (key) { case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break; + case 'cursorStyle': + // Style 'block' applies with no class + this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline'); + this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar'); + break; } }; From 9227aed90607820c5ca4ce92228a38ec0ad310ac Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 18 Jan 2017 10:30:35 -0800 Subject: [PATCH 054/211] Add InputHandler.setCursorStyle test --- src/InputHandler.test.ts | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/InputHandler.test.ts diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts new file mode 100644 index 00000000..ecc6bf9a --- /dev/null +++ b/src/InputHandler.test.ts @@ -0,0 +1,49 @@ +import { assert } from 'chai'; +import { InputHandler } from './InputHandler'; + +describe('InputHandler', () => { + describe('setCursorStyle', () => { + it('should call Terminal.setOption with correct params', () => { + let options = {}; + let terminal = { + setOption: (option, value) => options[option] = value + }; + let inputHandler = new InputHandler(terminal); + + inputHandler.setCursorStyle([0]); + assert.equal(options['cursorStyle'], 'block'); + assert.equal(options['cursorBlink'], true); + + options = {}; + inputHandler.setCursorStyle([1]); + assert.equal(options['cursorStyle'], 'block'); + assert.equal(options['cursorBlink'], true); + + options = {}; + inputHandler.setCursorStyle([2]); + assert.equal(options['cursorStyle'], 'block'); + assert.equal(options['cursorBlink'], false); + + options = {}; + inputHandler.setCursorStyle([3]); + assert.equal(options['cursorStyle'], 'underline'); + assert.equal(options['cursorBlink'], true); + + options = {}; + inputHandler.setCursorStyle([4]); + assert.equal(options['cursorStyle'], 'underline'); + assert.equal(options['cursorBlink'], false); + + options = {}; + inputHandler.setCursorStyle([5]); + assert.equal(options['cursorStyle'], 'bar'); + assert.equal(options['cursorBlink'], true); + + options = {}; + inputHandler.setCursorStyle([6]); + assert.equal(options['cursorStyle'], 'bar'); + assert.equal(options['cursorBlink'], false); + + }); + }); +}); From 9626b1e39db4ae2317f17822332dfcf5d7617343 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 19 Jan 2017 18:02:09 -0800 Subject: [PATCH 055/211] Only keep > 0 geometry in CharMeasure Fixes #494 --- src/utils/CharMeasure.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/utils/CharMeasure.ts b/src/utils/CharMeasure.ts index 6ca5046a..3344fed2 100644 --- a/src/utils/CharMeasure.ts +++ b/src/utils/CharMeasure.ts @@ -44,10 +44,12 @@ export class CharMeasure extends EventEmitter { } private _doMeasure(): void { - const oldWidth = this._width; - const oldHeight = this._height; const geometry = this._measureElement.getBoundingClientRect(); - + // The element is likely currently display:none, we should retain the + // previous value. + if (geometry.width === 0 || geometry.height === 0) { + return; + } if (this._width !== geometry.width || this._height !== geometry.height) { this._width = geometry.width; this._height = geometry.height; From f4293a6dfaed21512e90e978ddba42f60cc60f44 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Fri, 20 Jan 2017 16:47:34 +0200 Subject: [PATCH 056/211] Fix #488: Implement configurable tab width --- demo/index.html | 7 +++++-- demo/main.js | 12 +++++++++--- src/xterm.js | 5 +++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/demo/index.html b/demo/index.html index 764c8442..c3721a28 100644 --- a/demo/index.html +++ b/demo/index.html @@ -17,10 +17,13 @@

Options

- +

- + +

+

+

Size

diff --git a/demo/main.js b/demo/main.js index 078b5c8d..a5f8460e 100644 --- a/demo/main.js +++ b/demo/main.js @@ -9,7 +9,8 @@ var term, var terminalContainer = document.getElementById('terminal-container'), optionElements = { cursorBlink: document.querySelector('#option-cursor-blink'), - scrollback: document.querySelector('#option-scrollback') + scrollback: document.querySelector('#option-scrollback'), + tabstopwidth: document.querySelector('#option-tabstopwidth') }, colsElement = document.getElementById('cols'), rowsElement = document.getElementById('rows'); @@ -32,7 +33,11 @@ optionElements.cursorBlink.addEventListener('change', function () { term.setOption('cursorBlink', optionElements.cursorBlink.checked); }); optionElements.scrollback.addEventListener('change', function () { - terminal.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); + term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); +}); +optionElements.tabstopwidth.addEventListener('change', function () { + term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value)); + term.setupStops(); }); createTerminal(); @@ -44,7 +49,8 @@ function createTerminal() { } term = new Terminal({ cursorBlink: optionElements.cursorBlink.checked, - scrollback: parseInt(optionElements.scrollback.value, 10) + scrollback: parseInt(optionElements.scrollback.value, 10), + tabStopWidth: parseInt(optionElements.tabstopwidth.value) }); term.on('resize', function (size) { if (!pid) { diff --git a/src/xterm.js b/src/xterm.js index 7f50295f..3c205adb 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -360,7 +360,8 @@ Terminal.defaults = { screenKeys: false, debug: false, cancelEvents: false, - disableStdin: false + disableStdin: false, + tabStopWidth: 8 // programFeatures: false, // focusKeys: false, }; @@ -2118,7 +2119,7 @@ Terminal.prototype.setupStops = function(i) { i = 0; } - for (; i < this.cols; i += 8) { + for (; i < this.cols; i += this.getOption('tabStopWidth')) { this.tabs[i] = true; } }; From 8cb46f272605e8f7720435d0c7b4d5a14cc49280 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Fri, 20 Jan 2017 18:16:50 +0200 Subject: [PATCH 057/211] Move `tabStopWidth` option callback into `setOption` --- demo/main.js | 1 - src/xterm.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/main.js b/demo/main.js index a5f8460e..fda6c809 100644 --- a/demo/main.js +++ b/demo/main.js @@ -37,7 +37,6 @@ optionElements.scrollback.addEventListener('change', function () { }); optionElements.tabstopwidth.addEventListener('change', function () { term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value)); - term.setupStops(); }); createTerminal(); diff --git a/src/xterm.js b/src/xterm.js index 3c205adb..9e44f24f 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -434,6 +434,7 @@ Terminal.prototype.setOption = function(key, value) { this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline'); this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar'); break; + case 'tabStopWidth': this.setupStops(); break; } }; From 9a86e4e109b4caa3ac7c4f34fff03b91c6efd354 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 14:23:45 -0800 Subject: [PATCH 058/211] Fix setupStops call in resize Fixes #259 --- src/xterm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 7f50295f..99540891 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2003,8 +2003,8 @@ Terminal.prototype.resize = function(x, y) { } } } - this.setupStops(j); this.cols = x; + this.setupStops(this.cols); // resize rows j = this.rows; From 6e1628bc3b83896fbe3a63e068b01ce3a42484e3 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Sat, 21 Jan 2017 00:32:39 +0200 Subject: [PATCH 059/211] Fixes on demo based on configurable `tabStopWidth` --- demo/index.html | 4 ++-- demo/main.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/demo/index.html b/demo/index.html index c3721a28..0d8efac3 100644 --- a/demo/index.html +++ b/demo/index.html @@ -17,13 +17,13 @@

Options

- +

- +

Size

diff --git a/demo/main.js b/demo/main.js index fda6c809..b262ce53 100644 --- a/demo/main.js +++ b/demo/main.js @@ -16,8 +16,8 @@ var terminalContainer = document.getElementById('terminal-container'), rowsElement = document.getElementById('rows'); function setTerminalSize () { - var cols = parseInt(colsElement.value), - rows = parseInt(rowsElement.value), + var cols = parseInt(colsElement.value, 10), + rows = parseInt(rowsElement.value, 10), width = (cols * charWidth).toString() + 'px', height = (rows * charHeight).toString() + 'px'; @@ -36,7 +36,7 @@ optionElements.scrollback.addEventListener('change', function () { term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); }); optionElements.tabstopwidth.addEventListener('change', function () { - term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value)); + term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value, 10)); }); createTerminal(); @@ -49,7 +49,7 @@ function createTerminal() { term = new Terminal({ cursorBlink: optionElements.cursorBlink.checked, scrollback: parseInt(optionElements.scrollback.value, 10), - tabStopWidth: parseInt(optionElements.tabstopwidth.value) + tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10) }); term.on('resize', function (size) { if (!pid) { From 0461a822c29a6e110d6acb79b88cb1062d84b69c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 19:05:13 -0800 Subject: [PATCH 060/211] Add character sets for most languages Part of #481 --- src/Charsets.ts | 202 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 190 insertions(+), 12 deletions(-) diff --git a/src/Charsets.ts b/src/Charsets.ts index 3220f7d5..317d60e4 100644 --- a/src/Charsets.ts +++ b/src/Charsets.ts @@ -52,16 +52,194 @@ CHARSETS.SCLD = { // (0 '~': '\u00b7' // '·' }; -CHARSETS.UK = null; // (A -CHARSETS.US = null; // (B (USASCII) -CHARSETS.Dutch = null; // (4 -CHARSETS.Finnish = null; // (C or (5 -CHARSETS.French = null; // (R -CHARSETS.FrenchCanadian = null; // (Q -CHARSETS.German = null; // (K -CHARSETS.Italian = null; // (Y -CHARSETS.NorwegianDanish = null; // (E or (6 -CHARSETS.Spanish = null; // (Z -CHARSETS.Swedish = null; // (H or (7 -CHARSETS.Swiss = null; // (= +/** + * British character set + * ESC (A + * Reference: http://vt100.net/docs/vt220-rm/table2-5.html + */ +CHARSETS.UK = { + '#': '£' +}; + +/** + * United States character set + * ESC (B + */ +CHARSETS.US = null; + +/** + * Dutch character set + * ESC (4 + * Reference: http://vt100.net/docs/vt220-rm/table2-6.html + */ +CHARSETS.Dutch = { // (4 + '#': '£', + '@': '¾', + '[': 'ij', + '\\': '½', + ']': '|', + '{': '¨', + '|': 'f', + '}': '¼', + '~': '´' +}; + +/** + * Finnish character set + * ESC (C or ESC (5 + * Reference: http://vt100.net/docs/vt220-rm/table2-7.html + */ +CHARSETS.Finnish = { + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' +}; + +/** + * French character set + * ESC (R + * Reference: http://vt100.net/docs/vt220-rm/table2-8.html + */ +CHARSETS.French = { + '#': '£', + '@': 'à', + '[': '°', + '\\': 'ç', + ']': '§', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': '¨' +}; + +/** + * French Canadian character set + * ESC (Q + * Reference: http://vt100.net/docs/vt220-rm/table2-9.html + */ +CHARSETS.FrenchCanadian = { + '@': 'à', + '[': 'â', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '`': 'ô', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': 'û' +}; + +/** + * German character set + * ESC (K + * Reference: http://vt100.net/docs/vt220-rm/table2-10.html + */ +CHARSETS.German = { + '@': '§', + '[': 'Ä', + '\\': 'Ö', + ']': 'Ü', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'ß' +}; + +/** + * Italian character set + * ESC (Y + * Reference: http://vt100.net/docs/vt220-rm/table2-11.html + */ +CHARSETS.Italian = { + '#': '£', + '@': '§', + '[': '°', + '\\': 'ç', + ']': 'é', + '`': 'ù', + '{': 'à', + '|': 'ò', + '}': 'è', + '~': 'ì' +}; + +/** + * Norwegian/Danish character set + * ESC (E or ESC (6 + * Reference: http://vt100.net/docs/vt220-rm/table2-12.html + */ +CHARSETS.NorwegianDanish = { + '@': 'Ä', + '[': 'Æ', + '\\': 'Ø', + ']': 'Å', + '^': 'Ü', + '`': 'ä', + '{': 'æ', + '|': 'ø', + '}': 'å', + '~': 'ü' +}; + +/** + * Spanish character set + * ESC (Z + * Reference: http://vt100.net/docs/vt220-rm/table2-13.html + */ +CHARSETS.Spanish = { + '#': '£', + '@': '§', + '[': '¡', + '\\': 'Ñ', + ']': '¿', + '{': '°', + '|': 'ñ', + '}': 'ç' +}; + +/** + * Swedish character set + * ESC (H or ESC (7 + * Reference: http://vt100.net/docs/vt220-rm/table2-14.html + */ +CHARSETS.Swedish = { + '@': 'É', + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' +}; + +/** + * Swiss character set + * ESC (= + * Reference: http://vt100.net/docs/vt220-rm/table2-15.html + */ +CHARSETS.Swiss = { + '#': 'ù', + '@': 'à', + '[': 'é', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '_': 'è', + '`': 'ô', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'û' +}; + CHARSETS.ISOLatin = null; // /A From aab67c2ed97177be9e6a464a5c0b725e3eb48783 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 20:12:47 -0800 Subject: [PATCH 061/211] Reference CHARSETS using codes --- src/Charsets.ts | 41 +++++++++++++++++++++++------------------ src/InputHandler.ts | 10 +++++----- src/Parser.ts | 32 +++++--------------------------- 3 files changed, 33 insertions(+), 50 deletions(-) diff --git a/src/Charsets.ts b/src/Charsets.ts index 317d60e4..b3bdbbb4 100644 --- a/src/Charsets.ts +++ b/src/Charsets.ts @@ -2,13 +2,17 @@ * @license MIT */ -// TODO: Give CHARSETS a proper type /** * The character sets supported by the terminal. These enable several languages * to be represented within the terminal with only 8-bit encoding. See ISO 2022 - * for a discussion on character sets. + * for a discussion on character sets. Only VT100 character sets are supported. */ -export const CHARSETS: any = {}; +export const CHARSETS: {[key: string]: {[key: string]: string}} = {}; + +/** + * The default character set, US. + */ +export const DEFAULT_CHARSET = CHARSETS['B']; // DEC Special Character and Line Drawing Set. // http://vt100.net/docs/vt102-ug/table5-13.html @@ -18,7 +22,7 @@ export const CHARSETS: any = {}; // reference above. xterm seems in line with the reference // when running vttest however. // The table below now uses xterm's output from vttest. -CHARSETS.SCLD = { // (0 +CHARSETS['0'] = { '`': '\u25c6', // '◆' 'a': '\u2592', // '▒' 'b': '\u0009', // '\t' @@ -57,7 +61,7 @@ CHARSETS.SCLD = { // (0 * ESC (A * Reference: http://vt100.net/docs/vt220-rm/table2-5.html */ -CHARSETS.UK = { +CHARSETS['A'] = { '#': '£' }; @@ -65,14 +69,14 @@ CHARSETS.UK = { * United States character set * ESC (B */ -CHARSETS.US = null; +CHARSETS['B'] = null; /** * Dutch character set * ESC (4 * Reference: http://vt100.net/docs/vt220-rm/table2-6.html */ -CHARSETS.Dutch = { // (4 +CHARSETS['4'] = { '#': '£', '@': '¾', '[': 'ij', @@ -89,7 +93,8 @@ CHARSETS.Dutch = { // (4 * ESC (C or ESC (5 * Reference: http://vt100.net/docs/vt220-rm/table2-7.html */ -CHARSETS.Finnish = { +CHARSETS['C'] = +CHARSETS['5'] = { '[': 'Ä', '\\': 'Ö', ']': 'Å', @@ -106,7 +111,7 @@ CHARSETS.Finnish = { * ESC (R * Reference: http://vt100.net/docs/vt220-rm/table2-8.html */ -CHARSETS.French = { +CHARSETS['R'] = { '#': '£', '@': 'à', '[': '°', @@ -123,7 +128,7 @@ CHARSETS.French = { * ESC (Q * Reference: http://vt100.net/docs/vt220-rm/table2-9.html */ -CHARSETS.FrenchCanadian = { +CHARSETS['Q'] = { '@': 'à', '[': 'â', '\\': 'ç', @@ -141,7 +146,7 @@ CHARSETS.FrenchCanadian = { * ESC (K * Reference: http://vt100.net/docs/vt220-rm/table2-10.html */ -CHARSETS.German = { +CHARSETS['K'] = { '@': '§', '[': 'Ä', '\\': 'Ö', @@ -157,7 +162,7 @@ CHARSETS.German = { * ESC (Y * Reference: http://vt100.net/docs/vt220-rm/table2-11.html */ -CHARSETS.Italian = { +CHARSETS['Y'] = { '#': '£', '@': '§', '[': '°', @@ -175,7 +180,8 @@ CHARSETS.Italian = { * ESC (E or ESC (6 * Reference: http://vt100.net/docs/vt220-rm/table2-12.html */ -CHARSETS.NorwegianDanish = { +CHARSETS['E'] = +CHARSETS['6'] = { '@': 'Ä', '[': 'Æ', '\\': 'Ø', @@ -193,7 +199,7 @@ CHARSETS.NorwegianDanish = { * ESC (Z * Reference: http://vt100.net/docs/vt220-rm/table2-13.html */ -CHARSETS.Spanish = { +CHARSETS['Z'] = { '#': '£', '@': '§', '[': '¡', @@ -209,7 +215,8 @@ CHARSETS.Spanish = { * ESC (H or ESC (7 * Reference: http://vt100.net/docs/vt220-rm/table2-14.html */ -CHARSETS.Swedish = { +CHARSETS['H'] = +CHARSETS['7'] = { '@': 'É', '[': 'Ä', '\\': 'Ö', @@ -227,7 +234,7 @@ CHARSETS.Swedish = { * ESC (= * Reference: http://vt100.net/docs/vt220-rm/table2-15.html */ -CHARSETS.Swiss = { +CHARSETS['='] = { '#': 'ù', '@': 'à', '[': 'é', @@ -241,5 +248,3 @@ CHARSETS.Swiss = { '}': 'ü', '~': 'û' }; - -CHARSETS.ISOLatin = null; // /A diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 975d7c11..bed835b6 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -4,7 +4,7 @@ import { IInputHandler, ITerminal } from './Interfaces'; import { C0 } from './EscapeSequences'; -import { CHARSETS } from './Charsets'; +import { DEFAULT_CHARSET } from './Charsets'; /** * The terminal's standard implementation of IInputHandler, this handles all @@ -842,10 +842,10 @@ export class InputHandler implements IInputHandler { this._terminal.applicationCursor = true; break; case 2: - this._terminal.setgCharset(0, CHARSETS.US); - this._terminal.setgCharset(1, CHARSETS.US); - this._terminal.setgCharset(2, CHARSETS.US); - this._terminal.setgCharset(3, CHARSETS.US); + this._terminal.setgCharset(0, DEFAULT_CHARSET); + this._terminal.setgCharset(1, DEFAULT_CHARSET); + this._terminal.setgCharset(2, DEFAULT_CHARSET); + this._terminal.setgCharset(3, DEFAULT_CHARSET); // set VT100 mode here break; case 3: // 132 col mode diff --git a/src/Parser.ts b/src/Parser.ts index 02028005..8f5f3e69 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -4,7 +4,7 @@ import { C0 } from './EscapeSequences'; import { IInputHandler } from './Interfaces'; -import { CHARSETS } from './Charsets'; +import { CHARSETS, DEFAULT_CHARSET } from './Charsets'; const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {}; normalStateHandler[C0.BEL] = (parser, handler) => handler.bell(); @@ -70,7 +70,7 @@ escapedStateHandler['%'] = (parser, terminal) => { // ESC % Select default/utf-8 character set. // @ = default, G = utf-8 terminal.setgLevel(0); - terminal.setgCharset(0, CHARSETS.US); + terminal.setgCharset(0, DEFAULT_CHARSET); // US (default) parser.setState(ParserState.NORMAL); parser.skipNextChar(); }; @@ -145,28 +145,6 @@ csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); -// TODO: Many codes/charsets appear to not be supported -// See: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html -const charsetMap = { - '0': CHARSETS.SCLD, - 'A': CHARSETS.UK, // United Kingdom - 'B': CHARSETS.US, // United States (USASCII) - '4': CHARSETS.Dutch, - 'C': CHARSETS.Finnish, - '5': CHARSETS.Finnish, - 'f': CHARSETS.French, - 'Q': CHARSETS.FrenchCanadian, - 'K': CHARSETS.German, - 'Y': CHARSETS.Italian, - 'E': CHARSETS.NorwegianDanish, - '6': CHARSETS.NorwegianDanish, - 'Z': CHARSETS.Spanish, - 'H': CHARSETS.Swedish, - '7': CHARSETS.Swedish, - '=': CHARSETS.Swiss, - '/': CHARSETS.ISOLatin // ISOLatin is actually /A -}; - enum ParserState { NORMAL = 0, ESCAPED = 1, @@ -371,13 +349,13 @@ export class Parser { break; case ParserState.CHARSET: - if (ch in charsetMap) { - cs = charsetMap[ch]; + if (ch in CHARSETS) { + cs = CHARSETS[ch]; if (ch === '/') { // ISOLatin is actually /A this.skipNextChar(); } } else { - cs = CHARSETS.US; // Default + cs = DEFAULT_CHARSET; } this._terminal.setgCharset(this._terminal.gcharset, cs); this._terminal.gcharset = null; From b5d16ed7d7b6d2a98102877cda0c8b96ad91a035 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 20:13:45 -0800 Subject: [PATCH 062/211] Use block comment for SCLD --- src/Charsets.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Charsets.ts b/src/Charsets.ts index b3bdbbb4..f567ef44 100644 --- a/src/Charsets.ts +++ b/src/Charsets.ts @@ -14,14 +14,16 @@ export const CHARSETS: {[key: string]: {[key: string]: string}} = {}; */ export const DEFAULT_CHARSET = CHARSETS['B']; -// DEC Special Character and Line Drawing Set. -// http://vt100.net/docs/vt102-ug/table5-13.html -// A lot of curses apps use this if they see TERM=xterm. -// testing: echo -e '\e(0a\e(B' -// The xterm output sometimes seems to conflict with the -// reference above. xterm seems in line with the reference -// when running vttest however. -// The table below now uses xterm's output from vttest. +/** + * DEC Special Character and Line Drawing Set. + * Reference: http://vt100.net/docs/vt102-ug/table5-13.html + * A lot of curses apps use this if they see TERM=xterm. + * testing: echo -e '\e(0a\e(B' + * The xterm output sometimes seems to conflict with the + * reference above. xterm seems in line with the reference + * when running vttest however. + * The table below now uses xterm's output from vttest. + */ CHARSETS['0'] = { '`': '\u25c6', // '◆' 'a': '\u2592', // '▒' From 43c3349494c7b922577fa80d50a57b23896e0818 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 21:20:11 -0800 Subject: [PATCH 063/211] Prevent wraparound mode from overriding last character --- src/InputHandler.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 975d7c11..ff113f2d 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -60,7 +60,6 @@ export class InputHandler implements IInputHandler { this._terminal.scroll(); } } else { - this._terminal.x = this._terminal.cols - 1; if (ch_width === 2) // FIXME: check for xterm behavior return; } From d5f0fff5239185cba93819eab505a2b3fdfda515 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 21:22:16 -0800 Subject: [PATCH 064/211] Enable other tests and fix viewport check --- src/test/escape-sequences-test.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index 6c64b562..b077f916 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -56,7 +56,7 @@ function formatError(in_, out_, expected) { function terminalToString(term) { var result = ''; var line_s = ''; - for (var line=0; line Date: Fri, 20 Jan 2017 21:39:27 -0800 Subject: [PATCH 065/211] Right trim expected output, we don't care for now This fixes 2 tests --- src/test/escape-sequences-test.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index b077f916..1bbc4a26 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -102,7 +102,12 @@ describe('xterm output comparison', function() { var from_emulator = terminalToString(xterm); console.log = CONSOLE_LOG; var expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8'); - if (from_emulator != expected) { + // Some of the tests have whitespace on the right of lines, we trim all the linex + // from xterm.js so ignore this for now at least. + var expectedRightTrimmed = expected.split('\n').map(function (l) { + return l.replace(/\s+$/, ''); + }).join('\n'); + if (from_emulator != expectedRightTrimmed) { // uncomment to get noisy output throw new Error(formatError(in_file, from_emulator, expected)); // throw new Error('mismatch'); From 72063329fe19402e41e0b1ef33db6e7f4c28fc9f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 21:49:39 -0800 Subject: [PATCH 066/211] Fix index behavior Don't wrap cursor to column 0 after an index, fixes 2 tests --- src/xterm.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xterm.js b/src/xterm.js index 7ab69b8d..ca5b642e 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2303,6 +2303,9 @@ Terminal.prototype.index = function() { this.y--; this.scroll(); } + if (this.x >= this.cols) { + this.x--; + } }; From 99fbcd3d6587103b0e8684063afd85de71d448ce Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 22:14:18 -0800 Subject: [PATCH 067/211] Fix LF/VT/FF behavior Don't wrap cursor to column 0 after an index, fixes 2 tests --- src/InputHandler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index ff113f2d..8e6949ba 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -123,6 +123,9 @@ export class InputHandler implements IInputHandler { this._terminal.y--; this._terminal.scroll(); } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } } /** From 1b344ce789a82bd873cc96e69c2a86d18cef147b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 23:03:38 -0800 Subject: [PATCH 068/211] Implement CAN (Cancel, ^X) This helps partially pass t0014-CAN.in, it won't work 100% however due to the very complex parsing logic of vanilla xterm that gnome-terminal doesn't even seem to match. xterm's source seems to have multiple ignore cases for a set of characters such that an escape sequence like \e!!!!!! prints nothing as the ! continually gets ignored. Our current logic is we ignore the escape sequence immediately in this case and print the !. --- src/Parser.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 02028005..5390bd8f 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -74,6 +74,7 @@ escapedStateHandler['%'] = (parser, terminal) => { parser.setState(ParserState.NORMAL); parser.skipNextChar(); }; +escapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL); const csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {}; csiParamStateHandler['?'] = (parser) => parser.setPrefix('?'); @@ -94,8 +95,9 @@ csiParamStateHandler['"'] = (parser) => parser.setPostfix('"'); csiParamStateHandler[' '] = (parser) => parser.setPostfix(' '); csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); csiParamStateHandler[';'] = (parser) => parser.finalizeParam(); +csiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL); -const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string) => void} = {}; +const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {}; csiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params); csiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params); csiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params); @@ -144,6 +146,7 @@ csiStateHandler['q'] = (handler, params, prefix, postfix) => { csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); +csiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL); // TODO: Many codes/charsets appear to not be supported // See: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html @@ -477,7 +480,7 @@ export class Parser { case ParserState.CSI: if (ch in csiStateHandler) { - csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix); + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this); } else { this._terminal.error('Unknown CSI code: %s.', ch); } From d30fb89fde577631e8ca66bcb6fe53e1a3002bd0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 23:11:22 -0800 Subject: [PATCH 069/211] Fix CUB behavior Don't wrap cursor to column 0 after a CUB, fixes 3 tests --- src/InputHandler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 8e6949ba..6cb0f08c 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -246,6 +246,9 @@ export class InputHandler implements IInputHandler { if (param < 1) { param = 1; } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } this._terminal.x -= param; if (this._terminal.x < 0) { this._terminal.x = 0; From 74c3a4a6f76e687534625e326e894e092568281b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 23:12:54 -0800 Subject: [PATCH 070/211] Fix CUD behavior Don't wrap cursor to column 0 after a CUD, fixes 1 test --- src/InputHandler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 6cb0f08c..13a3145b 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -220,6 +220,9 @@ export class InputHandler implements IInputHandler { if (this._terminal.y >= this._terminal.rows) { this._terminal.y = this._terminal.rows - 1; } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } } /** From 2aa7608ac05f0effb1d8f04e43a1dfb32558d055 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 23:14:08 -0800 Subject: [PATCH 071/211] Fix VPR behavior Don't wrap cursor to column 0 after a VPR, fixes 1 test --- src/InputHandler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 13a3145b..bbf17b60 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -701,6 +701,9 @@ export class InputHandler implements IInputHandler { if (this._terminal.y >= this._terminal.rows) { this._terminal.y = this._terminal.rows - 1; } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } } /** From da16dd7cae952a85f301afb0b917a719a413870f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 23:20:13 -0800 Subject: [PATCH 072/211] Mock viewport.syncScrollArea --- src/test/escape-sequences-test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index 1bbc4a26..bc5d5bfe 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -76,6 +76,9 @@ describe('xterm output comparison', function() { beforeEach(function () { xterm = new Terminal(COLS, ROWS); xterm.refresh = function() {}; + xterm.viewport = { + syncScrollArea: function() {} + }; }); // omit stack trace for escape sequence files From 4f7ee7dab0d75656607dc764ee50bb317a10adc2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 20 Jan 2017 23:38:56 -0800 Subject: [PATCH 073/211] Skip broken tests --- src/test/escape-sequences-test.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index bc5d5bfe..f35bc00a 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -85,11 +85,16 @@ describe('xterm output comparison', function() { Error.stackTraceLimit = 0; var files = glob.sync('**/escape_sequence_files/*.in'); // only successful tests for now - var successful = [0, 2, 6, 12, 13, 18, 20, 22, 27, 28, 50]; + var skip = [ + 10, 16, 17, 19, 32, 33, 34, 35, 36, 39, + 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, + 63, 68 + ]; for (var i = 0; i < files.length; i++) { - // if (i !== 1) continue; - //for (var a in successful) { - // var i = successful[a]; + if (skip.indexOf(i) >= 0) { + continue; + } (function(filename) { it(filename.split('/').slice(-1)[0], function () { pty_reset(); From 1a55367fc944d0056f75ae6b0722f0131f0ee5ef Mon Sep 17 00:00:00 2001 From: Vincent Woo Date: Sun, 22 Jan 2017 22:26:40 -0800 Subject: [PATCH 074/211] Bundle top-level JS with npm --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 67eb824d..1029d59d 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "repository": "https://github.com/sourcelair/xterm.js", "license": "MIT", "files": [ + "*.js", "dist/*.css", "dist/**/*.css", "dist/*.js", From 537c8bad100531a0dbb1c272e76a8390798f1168 Mon Sep 17 00:00:00 2001 From: Vincent Woo Date: Sun, 22 Jan 2017 22:28:46 -0800 Subject: [PATCH 075/211] Bundle top-level JSON with npm --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1029d59d..d98059da 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "license": "MIT", "files": [ "*.js", + "*.json", "dist/*.css", "dist/**/*.css", "dist/*.js", From 9359dca0f36579eb0697145edfdccc92b161f223 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 23 Jan 2017 11:30:45 -0800 Subject: [PATCH 076/211] Use InputHandler.setMode/resetMode, not Terminal --- src/InputHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 975d7c11..6ec36e5f 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -821,7 +821,7 @@ export class InputHandler implements IInputHandler { public setMode(params: number[]): void { if (params.length > 1) { for (let i = 0; i < params.length; i++) { - this._terminal.setMode(params[i]); + this.setMode([params[i]]); } return; @@ -1027,7 +1027,7 @@ export class InputHandler implements IInputHandler { public resetMode(params: number[]): void { if (params.length > 1) { for (let i = 0; i < params.length; i++) { - this._terminal.resetMode(params[i]); + this.resetMode([params[i]]); } return; From e77148304117425e7d3f66e3b35e282c8c61e7a7 Mon Sep 17 00:00:00 2001 From: Vincent Woo Date: Mon, 23 Jan 2017 21:32:14 -0800 Subject: [PATCH 077/211] Add CoderPad to real world use cases Hi everyone, I'm very pleased to say I have cut CoderPad.io over to using xterm.js (replacing term.js). I've very pleased with the work you've done on it. You've implemented the many terrible hacks on top of term.js I had to write, except you've actually implemented stuff the right way. I look forward to your continued progress on the project! Cheers, Vincent --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f68da0f1..c251da48 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Katacoda**](https://www.katacoda.com/): Katacoda is an Interactive Learning Platform for software developers, covering the latest Cloud Native technologies. - [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE. - [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams. - +- [**CoderPad**](https://coderpad.io): Online interviewing platform for programmers. Run code in many programming languages, with results displayed by `xterm.js`. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From 3b166966727b149c2a256da848a2164b4b15790a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 24 Jan 2017 13:34:45 -0800 Subject: [PATCH 078/211] Run lint on src/*.ts and fix errors Fixes #507 --- package.json | 2 +- src/CompositionHelper.test.ts | 14 ++++----- src/CompositionHelper.ts | 53 +++++++++++++++++------------------ 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index d98059da..c05d97f2 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "prestart": "npm run build", "start": "node demo/app", "dev": "nodemon -e js,ts --watch src --watch demo --exec npm start", - "lint": "tslint src/**/*.ts", + "lint": "tslint src/*.ts src/**/*.ts", "test": "mocha --recursive ./lib", "build:docs": "jsdoc -c jsdoc.json", "build": "gulp build", diff --git a/src/CompositionHelper.test.ts b/src/CompositionHelper.test.ts index f0acd40e..4a96e12a 100644 --- a/src/CompositionHelper.test.ts +++ b/src/CompositionHelper.test.ts @@ -2,11 +2,11 @@ import { assert } from 'chai'; import { CompositionHelper } from './CompositionHelper'; describe('CompositionHelper', () => { - var terminal; - var compositionHelper; - var compositionView; - var textarea; - var handledText; + let terminal; + let compositionHelper; + let compositionView; + let textarea; + let handledText; beforeEach(() => { compositionView = { @@ -125,7 +125,7 @@ describe('CompositionHelper', () => { compositionHelper.compositionend(); compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: '아' }); - textarea.value = '아아' + textarea.value = '아아'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); setTimeout(() => { // wait for any textarea updates @@ -187,7 +187,7 @@ describe('CompositionHelper', () => { }, 0); }, 0); }, 0); - }) + }); it('Should insert multi-character compositions that are converted to other characters with different lengths', function (done) { // First character 'い' diff --git a/src/CompositionHelper.ts b/src/CompositionHelper.ts index 21c0a9e9..439e2085 100644 --- a/src/CompositionHelper.ts +++ b/src/CompositionHelper.ts @@ -24,7 +24,7 @@ export class CompositionHelper { /** * The position within the input textarea's value of the current composition. */ - private compositionPosition: IPosition;; + private compositionPosition: IPosition; /** * Whether a composition is in the process of being sent, setting this to false will cancel any @@ -65,9 +65,8 @@ export class CompositionHelper { public compositionupdate(ev: CompositionEvent) { this.compositionView.textContent = ev.data; this.updateCompositionElements(); - var self = this; - setTimeout(function() { - self.compositionPosition.end = self.textarea.value.length; + setTimeout(() => { + this.compositionPosition.end = this.textarea.value.length; }, 0); } @@ -125,15 +124,15 @@ export class CompositionHelper { if (!waitForPropogation) { // Cancel any delayed composition send requests and send the input immediately. this.isSendingComposition = false; - var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end); + const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end); this.terminal.handler(input); } else { // Make a deep copy of the composition position here as a new compositionstart event may // fire before the setTimeout executes. - var currentCompositionPosition = { + const currentCompositionPosition = { start: this.compositionPosition.start, end: this.compositionPosition.end, - } + }; // Since composition* events happen before the changes take place in the textarea on most // browsers, use a setTimeout with 0ms time to allow the native compositionend event to @@ -143,23 +142,22 @@ export class CompositionHelper { // - The last compositionupdate event's data property does not always accurately describe // the character, a counter example being Korean where an ending consonsant can move to // the following character if the following input is a vowel. - var self = this; this.isSendingComposition = true; - setTimeout(function () { + setTimeout(() => { // Ensure that the input has not already been sent - if (self.isSendingComposition) { - self.isSendingComposition = false; - var input; - if (self.isComposing) { + if (this.isSendingComposition) { + this.isSendingComposition = false; + let input; + if (this.isComposing) { // Use the end position to get the string if a new composition has started. - input = self.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end); + input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end); } else { // Don't use the end position here in order to pick up any characters after the // composition has finished, for example when typing a non-composition character // (eg. 2) after a composition character. - input = self.textarea.value.substring(currentCompositionPosition.start); + input = this.textarea.value.substring(currentCompositionPosition.start); } - self.terminal.handler(input); + this.terminal.handler(input); } }, 0); } @@ -172,15 +170,14 @@ export class CompositionHelper { * IME is active. */ private handleAnyTextareaChanges() { - var oldValue = this.textarea.value; - var self = this; - setTimeout(function() { + const oldValue = this.textarea.value; + setTimeout(() => { // Ignore if a composition has started since the timeout - if (!self.isComposing) { - var newValue = self.textarea.value; - var diff = newValue.replace(oldValue, ''); + if (!this.isComposing) { + const newValue = this.textarea.value; + const diff = newValue.replace(oldValue, ''); if (diff.length > 0) { - self.terminal.handler(diff); + this.terminal.handler(diff); } } }, 0); @@ -196,12 +193,12 @@ export class CompositionHelper { if (!this.isComposing) { return; } - var cursor = this.terminal.element.querySelector('.terminal-cursor'); + const cursor = this.terminal.element.querySelector('.terminal-cursor'); if (cursor) { // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within // the .xterm element. - var xtermRows = this.terminal.element.querySelector('.xterm-rows'); - var cursorTop = xtermRows.offsetTop + cursor.offsetTop; + const xtermRows = this.terminal.element.querySelector('.xterm-rows'); + const cursorTop = xtermRows.offsetTop + cursor.offsetTop; this.compositionView.style.left = cursor.offsetLeft + 'px'; this.compositionView.style.top = cursorTop + 'px'; @@ -209,7 +206,7 @@ export class CompositionHelper { this.compositionView.style.lineHeight = cursor.offsetHeight + 'px'; // Sync the textarea to the exact position of the composition view so the IME knows where the // text is. - var compositionViewBounds = this.compositionView.getBoundingClientRect(); + const compositionViewBounds = this.compositionView.getBoundingClientRect(); this.textarea.style.left = cursor.offsetLeft + 'px'; this.textarea.style.top = cursorTop + 'px'; this.textarea.style.width = compositionViewBounds.width + 'px'; @@ -217,7 +214,7 @@ export class CompositionHelper { this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; } if (!dontRecurse) { - setTimeout(this.updateCompositionElements.bind(this, true), 0); + setTimeout(() => this.updateCompositionElements(true), 0); } }; From 9f0dbdd5c7b80b761a75e97d95ded51d69219016 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 25 Jan 2017 10:25:28 -0800 Subject: [PATCH 079/211] Support debugging mocha tests from vscode --- .vscode/launch.json | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..064f0f5e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Mocha Tests", + "cwd": "${workspaceRoot}", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha", + "windows": { + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd" + }, + "runtimeArgs": [ + "--colors", + "--recursive", + "${workspaceRoot}/lib" + ], + "sourceMaps": true, + "outFiles": [ "${workspaceRoot}/lib/**/*.js" ], + "internalConsoleOptions": "openOnSessionStart" + } + ] +} From b789a7e85bc601f337be1d9d77f640c858bae17a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 25 Jan 2017 10:32:20 -0800 Subject: [PATCH 080/211] Fix failing test given new auto wraparound behavior --- src/test/test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/test.js b/src/test/test.js index 4f9342e5..890b9ad1 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -595,8 +595,9 @@ describe('xterm.js', function() { xterm.x = xterm.cols - 1; xterm.wraparoundMode = false; xterm.write('a' + high + String.fromCharCode(i)); - expect(xterm.lines.get(0)[xterm.cols-1][1]).eql(high + String.fromCharCode(i)); - expect(xterm.lines.get(0)[xterm.cols-1][1].length).eql(2); + // auto wraparound mode should cut off the rest of the line + expect(xterm.lines.get(0)[xterm.cols-1][1]).eql('a'); + expect(xterm.lines.get(0)[xterm.cols-1][1].length).eql(1); expect(xterm.lines.get(1)[1][1]).eql(' '); xterm.reset(); } From 5850cbcd0589aea9de269afed1eb3bcd9fc4e2ec Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 25 Jan 2017 10:34:43 -0800 Subject: [PATCH 081/211] Add comments explaining actions preventing x from wrapping --- src/InputHandler.ts | 4 ++++ src/xterm.js | 1 + 2 files changed, 5 insertions(+) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index bbf17b60..5dbdb420 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -123,6 +123,7 @@ export class InputHandler implements IInputHandler { this._terminal.y--; this._terminal.scroll(); } + // If the end of the line is hit, prevent this action from wrapping around to the next line. if (this._terminal.x >= this._terminal.cols) { this._terminal.x--; } @@ -220,6 +221,7 @@ export class InputHandler implements IInputHandler { if (this._terminal.y >= this._terminal.rows) { this._terminal.y = this._terminal.rows - 1; } + // If the end of the line is hit, prevent this action from wrapping around to the next line. if (this._terminal.x >= this._terminal.cols) { this._terminal.x--; } @@ -249,6 +251,7 @@ export class InputHandler implements IInputHandler { if (param < 1) { param = 1; } + // If the end of the line is hit, prevent this action from wrapping around to the next line. if (this._terminal.x >= this._terminal.cols) { this._terminal.x--; } @@ -701,6 +704,7 @@ export class InputHandler implements IInputHandler { if (this._terminal.y >= this._terminal.rows) { this._terminal.y = this._terminal.rows - 1; } + // If the end of the line is hit, prevent this action from wrapping around to the next line. if (this._terminal.x >= this._terminal.cols) { this._terminal.x--; } diff --git a/src/xterm.js b/src/xterm.js index ca5b642e..560db5fe 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2303,6 +2303,7 @@ Terminal.prototype.index = function() { this.y--; this.scroll(); } + // If the end of the line is hit, prevent this action from wrapping around to the next line. if (this.x >= this.cols) { this.x--; } From c2a69721f3a7568e9e2c4d4e3158e305383bc000 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 26 Jan 2017 21:14:07 -0800 Subject: [PATCH 082/211] Add useFlowControl option Fixes #511 --- src/xterm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 560db5fe..f88c9452 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -361,6 +361,7 @@ Terminal.defaults = { debug: false, cancelEvents: false, disableStdin: false, + useFlowControl: false, tabStopWidth: 8 // programFeatures: false, // focusKeys: false, @@ -1451,7 +1452,7 @@ Terminal.prototype.write = function(data) { // Send XOFF to pause the pty process if the write buffer becomes too large so // xterm.js can catch up before more data is sent. This is necessary in order // to keep signals such as ^C responsive. - if (!this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { + if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { // XOFF - stop pty pipe // XON will be triggered by emulator before processing data chunk this.send(C0.DC3); From 23c9fca088b9aebe53d90feb21e7623ebfa26ad7 Mon Sep 17 00:00:00 2001 From: Lucian Buzzo Date: Fri, 27 Jan 2017 11:25:12 +0000 Subject: [PATCH 083/211] [issue #164] Fix bug that can occur when setting a scroll region --- src/InputHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 4b96004e..55fb13ca 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1446,7 +1446,7 @@ export class InputHandler implements IInputHandler { public setScrollRegion(params: number[]): void { if (this._terminal.prefix) return; this._terminal.scrollTop = (params[0] || 1) - 1; - this._terminal.scrollBottom = (params[1] || this._terminal.rows) - 1; + this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1; this._terminal.x = 0; this._terminal.y = 0; } From 6cd5c2b8462c0c7a4ce898125a2fc7e0507fabc6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jan 2017 21:02:55 -0800 Subject: [PATCH 084/211] Add null checks in eraseRight and eraseLeft Fixes #519 --- src/xterm.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index f88c9452..ec4927c7 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2159,14 +2159,14 @@ Terminal.prototype.nextStop = function(x) { * @param {number} y The line in which to operate. */ Terminal.prototype.eraseRight = function(x, y) { - var line = this.lines.get(this.ybase + y) - , ch = [this.eraseAttr(), ' ', 1]; // xterm - - + var line = this.lines.get(this.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1]; // xterm for (; x < this.cols; x++) { line[x] = ch; } - this.updateRange(y); }; @@ -2178,12 +2178,15 @@ Terminal.prototype.eraseRight = function(x, y) { * @param {number} y The line in which to operate. */ Terminal.prototype.eraseLeft = function(x, y) { - var line = this.lines.get(this.ybase + y) - , ch = [this.eraseAttr(), ' ', 1]; // xterm - + var line = this.lines.get(this.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1]; // xterm x++; - while (x--) line[x] = ch; - + while (x--) { + line[x] = ch; + } this.updateRange(y); }; From 637a5bd9cc232bf33022d87bef484c62f0c5dfb0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jan 2017 21:23:21 -0800 Subject: [PATCH 085/211] Don't requeue animation frame if not needed Fixes #517 --- src/xterm.js | 64 +++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index f88c9452..fa8d6ad4 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -222,6 +222,7 @@ function Terminal(options) { this.writeBuffer = []; this.writeInProgress = false; this.refreshFramesSkipped = 0; + this.refreshAnimationFrame = null; /** * Whether _xterm.js_ sent XOFF in order to catch up with the pty process. @@ -659,7 +660,6 @@ Terminal.prototype.open = function(parent) { // Setup loop that draws to screen this.queueRefresh(0, this.rows - 1); - this.refreshLoop(); // Initialize global actions that // need to be taken on the document. @@ -1085,6 +1085,9 @@ Terminal.flags = { */ Terminal.prototype.queueRefresh = function(start, end) { this.refreshRowsQueue.push({ start: start, end: end }); + if (!this.refreshAnimationFrame) { + this.refreshAnimationFrame = window.requestAnimationFrame(this.refreshLoop.bind(this)); + } } /** @@ -1092,40 +1095,39 @@ Terminal.prototype.queueRefresh = function(start, end) { * necessary before queueing up the next one. */ Terminal.prototype.refreshLoop = function() { - // Don't refresh if there were no row changes - if (this.refreshRowsQueue.length > 0) { - // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it - // will need to be immediately refreshed anyway. This saves a lot of - // rendering time as the viewport DOM does not need to be refreshed, no - // scroll events, no layouts, etc. - var skipFrame = this.writeBuffer.length > 0 && this.refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it + // will need to be immediately refreshed anyway. This saves a lot of + // rendering time as the viewport DOM does not need to be refreshed, no + // scroll events, no layouts, etc. + var skipFrame = this.writeBuffer.length > 0 && this.refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + if (skipFrame) { + this.refreshAnimationFrame = window.requestAnimationFrame(this.refreshLoop.bind(this)); + return; + } - if (!skipFrame) { - this.refreshFramesSkipped = 0; - var start; - var end; - if (this.refreshRowsQueue.length > 4) { - // Just do a full refresh when 5+ refreshes are queued - start = 0; - end = this.rows - 1; - } else { - // Get start and end rows that need refreshing - start = this.refreshRowsQueue[0].start; - end = this.refreshRowsQueue[0].end; - for (var i = 1; i < this.refreshRowsQueue.length; i++) { - if (this.refreshRowsQueue[i].start < start) { - start = this.refreshRowsQueue[i].start; - } - if (this.refreshRowsQueue[i].end > end) { - end = this.refreshRowsQueue[i].end; - } - } + this.refreshFramesSkipped = 0; + var start; + var end; + if (this.refreshRowsQueue.length > 4) { + // Just do a full refresh when 5+ refreshes are queued + start = 0; + end = this.rows - 1; + } else { + // Get start and end rows that need refreshing + start = this.refreshRowsQueue[0].start; + end = this.refreshRowsQueue[0].end; + for (var i = 1; i < this.refreshRowsQueue.length; i++) { + if (this.refreshRowsQueue[i].start < start) { + start = this.refreshRowsQueue[i].start; + } + if (this.refreshRowsQueue[i].end > end) { + end = this.refreshRowsQueue[i].end; } - this.refreshRowsQueue = []; - this.refresh(start, end); } } - window.requestAnimationFrame(this.refreshLoop.bind(this)); + this.refreshRowsQueue = []; + this.refreshAnimationFrame = null; + this.refresh(start, end); } /** From 047729ee9e0901dcd3eaa0f35fecfb3d2a39725a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jan 2017 21:23:21 -0800 Subject: [PATCH 086/211] Don't requeue animation frame if not needed Fixes #517 --- src/xterm.js | 64 +++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index f88c9452..fa8d6ad4 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -222,6 +222,7 @@ function Terminal(options) { this.writeBuffer = []; this.writeInProgress = false; this.refreshFramesSkipped = 0; + this.refreshAnimationFrame = null; /** * Whether _xterm.js_ sent XOFF in order to catch up with the pty process. @@ -659,7 +660,6 @@ Terminal.prototype.open = function(parent) { // Setup loop that draws to screen this.queueRefresh(0, this.rows - 1); - this.refreshLoop(); // Initialize global actions that // need to be taken on the document. @@ -1085,6 +1085,9 @@ Terminal.flags = { */ Terminal.prototype.queueRefresh = function(start, end) { this.refreshRowsQueue.push({ start: start, end: end }); + if (!this.refreshAnimationFrame) { + this.refreshAnimationFrame = window.requestAnimationFrame(this.refreshLoop.bind(this)); + } } /** @@ -1092,40 +1095,39 @@ Terminal.prototype.queueRefresh = function(start, end) { * necessary before queueing up the next one. */ Terminal.prototype.refreshLoop = function() { - // Don't refresh if there were no row changes - if (this.refreshRowsQueue.length > 0) { - // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it - // will need to be immediately refreshed anyway. This saves a lot of - // rendering time as the viewport DOM does not need to be refreshed, no - // scroll events, no layouts, etc. - var skipFrame = this.writeBuffer.length > 0 && this.refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it + // will need to be immediately refreshed anyway. This saves a lot of + // rendering time as the viewport DOM does not need to be refreshed, no + // scroll events, no layouts, etc. + var skipFrame = this.writeBuffer.length > 0 && this.refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + if (skipFrame) { + this.refreshAnimationFrame = window.requestAnimationFrame(this.refreshLoop.bind(this)); + return; + } - if (!skipFrame) { - this.refreshFramesSkipped = 0; - var start; - var end; - if (this.refreshRowsQueue.length > 4) { - // Just do a full refresh when 5+ refreshes are queued - start = 0; - end = this.rows - 1; - } else { - // Get start and end rows that need refreshing - start = this.refreshRowsQueue[0].start; - end = this.refreshRowsQueue[0].end; - for (var i = 1; i < this.refreshRowsQueue.length; i++) { - if (this.refreshRowsQueue[i].start < start) { - start = this.refreshRowsQueue[i].start; - } - if (this.refreshRowsQueue[i].end > end) { - end = this.refreshRowsQueue[i].end; - } - } + this.refreshFramesSkipped = 0; + var start; + var end; + if (this.refreshRowsQueue.length > 4) { + // Just do a full refresh when 5+ refreshes are queued + start = 0; + end = this.rows - 1; + } else { + // Get start and end rows that need refreshing + start = this.refreshRowsQueue[0].start; + end = this.refreshRowsQueue[0].end; + for (var i = 1; i < this.refreshRowsQueue.length; i++) { + if (this.refreshRowsQueue[i].start < start) { + start = this.refreshRowsQueue[i].start; + } + if (this.refreshRowsQueue[i].end > end) { + end = this.refreshRowsQueue[i].end; } - this.refreshRowsQueue = []; - this.refresh(start, end); } } - window.requestAnimationFrame(this.refreshLoop.bind(this)); + this.refreshRowsQueue = []; + this.refreshAnimationFrame = null; + this.refresh(start, end); } /** From 92068f36f2e02ec4c10c4f88f6f79f8ce9fbcd61 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jan 2017 22:45:28 -0800 Subject: [PATCH 087/211] Pull renderer out of xterm.js --- src/Interfaces.ts | 27 ++++- src/Renderer.ts | 303 ++++++++++++++++++++++++++++++++++++++++++++++ src/xterm.js | 298 +++------------------------------------------ 3 files changed, 345 insertions(+), 283 deletions(-) create mode 100644 src/Renderer.ts diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 049a599c..c876d256 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -18,10 +18,19 @@ export interface ITerminal { element: HTMLElement; rowContainer: HTMLElement; textarea: HTMLTextAreaElement; + ybase: number; ydisp: number; - lines: string[]; + lines: ICircularList; rows: number; + cols: number; browser: IBrowser; + writeBuffer: string[]; + children: HTMLElement[]; + cursorHidden: boolean; + cursorState: number; + x: number; + y: number; + defAttr: number; /** * Emit the 'data' event and populate the given data. @@ -31,6 +40,22 @@ export interface ITerminal { on(event: string, callback: () => void); scrollDisp(disp: number, suppressScrollEvent: boolean); cancel(ev: Event, force?: boolean); + log(text: string): void; + emit(event: string, data: any); +} + +interface ICircularList { + length: number; + maxLength: number; + + forEach(callbackfn: (value: T, index: number, array: T[]) => void): void; + get(index: number): T; + set(index: number, value: T): void; + push(value: T): void; + pop(): T; + splice(start: number, deleteCount: number, ...items: T[]): void; + trimStart(count: number): void; + shiftElements(start: number, count: number, offset: number): void; } /** diff --git a/src/Renderer.ts b/src/Renderer.ts new file mode 100644 index 00000000..e43c77a2 --- /dev/null +++ b/src/Renderer.ts @@ -0,0 +1,303 @@ +import { ITerminal } from './Interfaces'; + +/** + * The maximum number of refresh frames to skip when the write buffer is non- + * empty. Note that these frames may be intermingled with frames that are + * skipped via requestAnimationFrame's mechanism. + */ +const MAX_REFRESH_FRAME_SKIP = 5; + +// TODO: Convert flags to number enum +/** + * Flags used to render terminal text properly + */ +const FLAGS = { + BOLD: 1, + UNDERLINE: 2, + BLINK: 4, + INVERSE: 8, + INVISIBLE: 16 +}; + +let brokenBold: boolean = null; + +export class Renderer { + /** A queue of the rows to be refreshed */ + private _refreshRowsQueue: {start: number, end: number}[] = []; + private _refreshFramesSkipped = 0; + private _refreshAnimationFrame = null; + + constructor(private _terminal: ITerminal) { + // Figure out whether boldness affects + // the character width of monospace fonts. + if (brokenBold === null) { + brokenBold = checkBoldBroken((this._terminal).document); + console.log('check brokenBold: ' + brokenBold); + } + + // TODO: Pull all DOM interactions into Renderer.constructor + } + + /** + * Queues a refresh between two rows (inclusive), to be done on next animation + * frame. + * @param {number} start The start row. + * @param {number} end The end row. + */ + public queueRefresh(start: number, end: number): void { + this._refreshRowsQueue.push({ start: start, end: end }); + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + } + } + + /** + * Performs the refresh loop callback, calling refresh only if a refresh is + * necessary before queueing up the next one. + */ + private _refreshLoop(): void { + // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it + // will need to be immediately refreshed anyway. This saves a lot of + // rendering time as the viewport DOM does not need to be refreshed, no + // scroll events, no layouts, etc. + const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + if (skipFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + return; + } + + this._refreshFramesSkipped = 0; + let start; + let end; + if (this._refreshRowsQueue.length > 4) { + // Just do a full refresh when 5+ refreshes are queued + start = 0; + end = this._terminal.rows - 1; + } else { + // Get start and end rows that need refreshing + start = this._refreshRowsQueue[0].start; + end = this._refreshRowsQueue[0].end; + for (let i = 1; i < this._refreshRowsQueue.length; i++) { + if (this._refreshRowsQueue[i].start < start) { + start = this._refreshRowsQueue[i].start; + } + if (this._refreshRowsQueue[i].end > end) { + end = this._refreshRowsQueue[i].end; + } + } + } + this._refreshRowsQueue = []; + this._refreshAnimationFrame = null; + this._refresh(start, end); + } + + /** + * Refreshes (re-renders) terminal content within two rows (inclusive) + * + * Rendering Engine: + * + * In the screen buffer, each character is stored as a an array with a character + * and a 32-bit integer: + * - First value: a utf-16 character. + * - Second value: + * - Next 9 bits: background color (0-511). + * - Next 9 bits: foreground color (0-511). + * - Next 14 bits: a mask for misc. flags: + * - 1=bold + * - 2=underline + * - 4=blink + * - 8=inverse + * - 16=invisible + * + * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) + * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) + */ + private _refresh(start: number, end: number): void { + // TODO: Use fat arrow functions for callbacks to avoid `self` + let self = this; + + let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement; + + // If this is a big refresh, remove the terminal rows from the DOM for faster calculations + if (end - start >= this._terminal.rows / 2) { + parent = this._terminal.element.parentNode; + if (parent) { + this._terminal.element.removeChild(this._terminal.rowContainer); + } + } + + width = this._terminal.cols; + y = start; + + if (end >= this._terminal.rows) { + this._terminal.log('`end` is too large. Most likely a bad CSR.'); + end = this._terminal.rows - 1; + } + + for (; y <= end; y++) { + row = y + this._terminal.ydisp; + + line = this._terminal.lines.get(row); + if (!line || !this._terminal.children[y]) { + // Continue if the line is not available, this means a resize is currently in progress + continue; + } + out = ''; + + if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp) + && this._terminal.cursorState + && !this._terminal.cursorHidden) { + x = this._terminal.x; + } else { + x = -1; + } + + attr = this._terminal.defAttr; + i = 0; + + for (; i < width; i++) { + if (!line[i]) { + // Continue if the character is not available, this means a resize is currently in progress + continue; + } + data = line[i][0]; + ch = line[i][1]; + ch_width = line[i][2]; + if (!ch_width) + continue; + + if (i === x) data = -1; + + if (data !== attr) { + if (attr !== this._terminal.defAttr) { + out += ''; + } + if (data !== this._terminal.defAttr) { + if (data === -1) { + out += ''; + } else { + let classNames = []; + + bg = data & 0x1ff; + fg = (data >> 9) & 0x1ff; + flags = data >> 18; + + if (flags & FLAGS.BOLD) { + if (!brokenBold) { + classNames.push('xterm-bold'); + } + // See: XTerm*boldColors + if (fg < 8) fg += 8; + } + + if (flags & FLAGS.UNDERLINE) { + classNames.push('xterm-underline'); + } + + if (flags & FLAGS.BLINK) { + classNames.push('xterm-blink'); + } + + // If inverse flag is on, then swap the foreground and background variables. + if (flags & FLAGS.INVERSE) { + /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */ + bg = [fg, fg = bg][0]; + // Should inverse just be before the + // above boldColors effect instead? + if ((flags & 1) && fg < 8) fg += 8; + } + + if (flags & FLAGS.INVISIBLE) { + classNames.push('xterm-hidden'); + } + + /** + * Weird situation: Invert flag used black foreground and white background results + * in invalid background color, positioned at the 256 index of the 256 terminal + * color map. Pin the colors manually in such a case. + * + * Source: https://github.com/sourcelair/xterm.js/issues/57 + */ + if (flags & FLAGS.INVERSE) { + if (bg === 257) { + bg = 15; + } + if (fg === 256) { + fg = 0; + } + } + + if (bg < 256) { + classNames.push('xterm-bg-color-' + bg); + } + + if (fg < 256) { + classNames.push('xterm-color-' + fg); + } + + out += '': + out += '>'; + break; + default: + if (ch <= ' ') { + out += ' '; + } else { + out += ch; + } + break; + } + if (ch_width === 2) { + out += ''; + } + + attr = data; + } + + if (attr !== this._terminal.defAttr) { + out += ''; + } + + this._terminal.children[y].innerHTML = out; + } + + if (parent) { + this._terminal.element.appendChild(this._terminal.rowContainer); + } + + this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end}); + }; +} + + +// if bold is broken, we can't +// use it in the terminal. +function checkBoldBroken(document) { + const body = document.getElementsByTagName('body')[0]; + const el = document.createElement('span'); + el.innerHTML = 'hello world'; + body.appendChild(el); + const w1 = el.scrollWidth; + el.style.fontWeight = 'bold'; + const w2 = el.scrollWidth; + body.removeChild(el); + return w1 !== w2; +} diff --git a/src/xterm.js b/src/xterm.js index fa8d6ad4..49e0b531 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -18,6 +18,7 @@ import { CircularList } from './utils/CircularList'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; import { Parser } from './Parser'; +import { Renderer } from './Renderer'; import { CharMeasure } from './utils/CharMeasure'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -50,13 +51,6 @@ var WRITE_BUFFER_PAUSE_THRESHOLD = 5; */ var WRITE_BATCH_SIZE = 300; -/** - * The maximum number of refresh frames to skip when the write buffer is non- - * empty. Note that these frames may be intermingled with frames that are - * skipped via requestAnimationFrame's mechanism. - */ -var MAX_REFRESH_FRAME_SKIP = 5; - /** * Terminal */ @@ -157,9 +151,6 @@ function Terminal(options) { */ this.y = 0; - /** A queue of the rows to be refreshed */ - this.refreshRowsQueue = []; - this.cursorState = 0; this.cursorHidden = false; this.convertEol; @@ -217,12 +208,11 @@ function Terminal(options) { this.inputHandler = new InputHandler(this); this.parser = new Parser(this.inputHandler, this); + this.renderer = null; // user input states this.writeBuffer = []; this.writeInProgress = false; - this.refreshFramesSkipped = 0; - this.refreshAnimationFrame = null; /** * Whether _xterm.js_ sent XOFF in order to catch up with the pty process. @@ -657,6 +647,7 @@ Terminal.prototype.open = function(parent) { this.charMeasure.measure(); this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); + this.renderer = new Renderer(this); // Setup loop that draws to screen this.queueRefresh(0, this.rows - 1); @@ -681,12 +672,6 @@ Terminal.prototype.open = function(parent) { // them into terminal mouse protocols. this.bindMouse(); - // Figure out whether boldness affects - // the character width of monospace fonts. - if (Terminal.brokenBold == null) { - Terminal.brokenBold = isBoldBroken(this.document); - } - /** * This event is emitted when terminal has completed opening. * @@ -1065,263 +1050,26 @@ Terminal.prototype.destroy = function() { //this.emit('close'); }; - /** - * Flags used to render terminal text properly - */ -Terminal.flags = { - BOLD: 1, - UNDERLINE: 2, - BLINK: 4, - INVERSE: 8, - INVISIBLE: 16 -} - -/** - * Queues a refresh between two rows (inclusive), to be done on next animation - * frame. - * @param {number} start The start row. - * @param {number} end The end row. - */ -Terminal.prototype.queueRefresh = function(start, end) { - this.refreshRowsQueue.push({ start: start, end: end }); - if (!this.refreshAnimationFrame) { - this.refreshAnimationFrame = window.requestAnimationFrame(this.refreshLoop.bind(this)); - } -} - -/** - * Performs the refresh loop callback, calling refresh only if a refresh is - * necessary before queueing up the next one. - */ -Terminal.prototype.refreshLoop = function() { - // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it - // will need to be immediately refreshed anyway. This saves a lot of - // rendering time as the viewport DOM does not need to be refreshed, no - // scroll events, no layouts, etc. - var skipFrame = this.writeBuffer.length > 0 && this.refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; - if (skipFrame) { - this.refreshAnimationFrame = window.requestAnimationFrame(this.refreshLoop.bind(this)); - return; - } - - this.refreshFramesSkipped = 0; - var start; - var end; - if (this.refreshRowsQueue.length > 4) { - // Just do a full refresh when 5+ refreshes are queued - start = 0; - end = this.rows - 1; - } else { - // Get start and end rows that need refreshing - start = this.refreshRowsQueue[0].start; - end = this.refreshRowsQueue[0].end; - for (var i = 1; i < this.refreshRowsQueue.length; i++) { - if (this.refreshRowsQueue[i].start < start) { - start = this.refreshRowsQueue[i].start; - } - if (this.refreshRowsQueue[i].end > end) { - end = this.refreshRowsQueue[i].end; - } - } - } - this.refreshRowsQueue = []; - this.refreshAnimationFrame = null; - this.refresh(start, end); -} - -/** - * Refreshes (re-renders) terminal content within two rows (inclusive) - * - * Rendering Engine: - * - * In the screen buffer, each character is stored as a an array with a character - * and a 32-bit integer: - * - First value: a utf-16 character. - * - Second value: - * - Next 9 bits: background color (0-511). - * - Next 9 bits: foreground color (0-511). - * - Next 14 bits: a mask for misc. flags: - * - 1=bold - * - 2=underline - * - 4=blink - * - 8=inverse - * - 16=invisible - * + * Tells the renderer to refresh terminal content between two rows (inclusive) at the next + * opportunity. * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) */ Terminal.prototype.refresh = function(start, end) { - var self = this; + this.queueRefresh(start, end); +}; - var x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement; - - // If this is a big refresh, remove the terminal rows from the DOM for faster calculations - if (end - start >= this.rows / 2) { - parent = this.element.parentNode; - if (parent) { - this.element.removeChild(this.rowContainer); - } +/** + * Tells the renderer to refresh terminal content between two rows (inclusive) at the next + * opportunity. + * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) + * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) + */ +Terminal.prototype.queueRefresh = function(start, end) { + if (this.renderer) { + this.renderer.queueRefresh(start, end); } - - width = this.cols; - y = start; - - if (end >= this.rows.length) { - this.log('`end` is too large. Most likely a bad CSR.'); - end = this.rows.length - 1; - } - - for (; y <= end; y++) { - row = y + this.ydisp; - - line = this.lines.get(row); - if (!line || !this.children[y]) { - // Continue if the line is not available, this means a resize is currently in progress - continue; - } - out = ''; - - if (this.y === y - (this.ybase - this.ydisp) - && this.cursorState - && !this.cursorHidden) { - x = this.x; - } else { - x = -1; - } - - attr = this.defAttr; - i = 0; - - for (; i < width; i++) { - if (!line[i]) { - // Continue if the character is not available, this means a resize is currently in progress - continue; - } - data = line[i][0]; - ch = line[i][1]; - ch_width = line[i][2]; - if (!ch_width) - continue; - - if (i === x) data = -1; - - if (data !== attr) { - if (attr !== this.defAttr) { - out += ''; - } - if (data !== this.defAttr) { - if (data === -1) { - out += ''; - } else { - var classNames = []; - - bg = data & 0x1ff; - fg = (data >> 9) & 0x1ff; - flags = data >> 18; - - if (flags & Terminal.flags.BOLD) { - if (!Terminal.brokenBold) { - classNames.push('xterm-bold'); - } - // See: XTerm*boldColors - if (fg < 8) fg += 8; - } - - if (flags & Terminal.flags.UNDERLINE) { - classNames.push('xterm-underline'); - } - - if (flags & Terminal.flags.BLINK) { - classNames.push('xterm-blink'); - } - - // If inverse flag is on, then swap the foreground and background variables. - if (flags & Terminal.flags.INVERSE) { - /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */ - bg = [fg, fg = bg][0]; - // Should inverse just be before the - // above boldColors effect instead? - if ((flags & 1) && fg < 8) fg += 8; - } - - if (flags & Terminal.flags.INVISIBLE) { - classNames.push('xterm-hidden'); - } - - /** - * Weird situation: Invert flag used black foreground and white background results - * in invalid background color, positioned at the 256 index of the 256 terminal - * color map. Pin the colors manually in such a case. - * - * Source: https://github.com/sourcelair/xterm.js/issues/57 - */ - if (flags & Terminal.flags.INVERSE) { - if (bg == 257) { - bg = 15; - } - if (fg == 256) { - fg = 0; - } - } - - if (bg < 256) { - classNames.push('xterm-bg-color-' + bg); - } - - if (fg < 256) { - classNames.push('xterm-color-' + fg); - } - - out += '': - out += '>'; - break; - default: - if (ch <= ' ') { - out += ' '; - } else { - out += ch; - } - break; - } - if (ch_width === 2) { - out += ''; - } - - attr = data; - } - - if (attr !== this.defAttr) { - out += ''; - } - - this.children[y].innerHTML = out; - } - - if (parent) { - this.element.appendChild(this.rowContainer); - } - - this.emit('refresh', {element: this.element, start: start, end: end}); }; /** @@ -2389,20 +2137,6 @@ function inherits(child, parent) { child.prototype = new f; } -// if bold is broken, we can't -// use it in the terminal. -function isBoldBroken(document) { - var body = document.getElementsByTagName('body')[0]; - var el = document.createElement('span'); - el.innerHTML = 'hello world'; - body.appendChild(el); - var w1 = el.scrollWidth; - el.style.fontWeight = 'bold'; - var w2 = el.scrollWidth; - body.removeChild(el); - return w1 !== w2; -} - function indexOf(obj, el) { var i = obj.length; while (i--) { From f9aac1bcc6f40743c58aa087f50f37e6e2435bbc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jan 2017 23:46:58 -0800 Subject: [PATCH 088/211] Fix tests --- src/test/escape-sequences-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index f35bc00a..684de079 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -75,7 +75,7 @@ describe('xterm output comparison', function() { beforeEach(function () { xterm = new Terminal(COLS, ROWS); - xterm.refresh = function() {}; + xterm.queueRefresh = function() {}; xterm.viewport = { syncScrollArea: function() {} }; From ca4e99e810cfa930d5c1402b1f262c02e768eb88 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Feb 2017 10:21:43 -0800 Subject: [PATCH 089/211] Add license --- src/Renderer.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Renderer.ts b/src/Renderer.ts index e43c77a2..15f36e69 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -1,3 +1,7 @@ +/** + * @license MIT + */ + import { ITerminal } from './Interfaces'; /** From 9d8f6c9ae7de96439933fa0d5af45597191090ea Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Feb 2017 10:30:58 -0800 Subject: [PATCH 090/211] Polish --- src/Renderer.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Renderer.ts b/src/Renderer.ts index 15f36e69..d99f9be4 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -36,10 +36,11 @@ export class Renderer { // the character width of monospace fonts. if (brokenBold === null) { brokenBold = checkBoldBroken((this._terminal).document); - console.log('check brokenBold: ' + brokenBold); } - // TODO: Pull all DOM interactions into Renderer.constructor + // TODO: Pull more DOM interactions into Renderer.constructor, element for + // example should be owned by Renderer (and also exposed by Terminal due to + // to established public API). } /** From 3c635f3ce52b28f62a074ed29787f670821ca8c4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Feb 2017 11:13:00 -0800 Subject: [PATCH 091/211] Remove Terminal.queueRefresh, call refresh directly --- src/InputHandler.ts | 2 +- src/test/escape-sequences-test.js | 2 +- src/test/test.js | 4 ---- src/xterm.js | 26 ++++++++------------------ 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 55fb13ca..10e72e9d 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1125,7 +1125,7 @@ export class InputHandler implements IInputHandler { // this.x = this.savedX; // this.y = this.savedY; // } - this._terminal.queueRefresh(0, this._terminal.rows - 1); + this._terminal.refresh(0, this._terminal.rows - 1); this._terminal.viewport.syncScrollArea(); this._terminal.showCursor(); } diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index 684de079..f35bc00a 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -75,7 +75,7 @@ describe('xterm output comparison', function() { beforeEach(function () { xterm = new Terminal(COLS, ROWS); - xterm.queueRefresh = function() {}; + xterm.refresh = function() {}; xterm.viewport = { syncScrollArea: function() {} }; diff --git a/src/test/test.js b/src/test/test.js index 890b9ad1..d0d70686 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -14,10 +14,6 @@ describe('xterm.js', function() { xterm.compositionHelper = { keydown: function(){ return true; } }; - // Force synchronous refreshes - xterm.queueRefresh = function(start, end) { - xterm.refresh(start, end); - }; // Force synchronous writes xterm.write = function(data) { xterm.writeBuffer.push(data); diff --git a/src/xterm.js b/src/xterm.js index d43ce91e..0229df90 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -461,7 +461,7 @@ Terminal.prototype.blur = function() { */ Terminal.bindBlur = function (term) { on(term.textarea, 'blur', function (ev) { - term.queueRefresh(term.y, term.y); + term.refresh(term.y, term.y); if (term.sendFocus) { term.send(C0.ESC + '[O'); } @@ -650,7 +650,7 @@ Terminal.prototype.open = function(parent) { this.renderer = new Renderer(this); // Setup loop that draws to screen - this.queueRefresh(0, this.rows - 1); + this.refresh(0, this.rows - 1); // Initialize global actions that // need to be taken on the document. @@ -1057,16 +1057,6 @@ Terminal.prototype.destroy = function() { * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) */ Terminal.prototype.refresh = function(start, end) { - this.queueRefresh(start, end); -}; - -/** - * Tells the renderer to refresh terminal content between two rows (inclusive) at the next - * opportunity. - * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) - * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) - */ -Terminal.prototype.queueRefresh = function(start, end) { if (this.renderer) { this.renderer.queueRefresh(start, end); } @@ -1078,7 +1068,7 @@ Terminal.prototype.queueRefresh = function(start, end) { Terminal.prototype.showCursor = function() { if (!this.cursorState) { this.cursorState = 1; - this.queueRefresh(this.y, this.y); + this.refresh(this.y, this.y); } }; @@ -1167,7 +1157,7 @@ Terminal.prototype.scrollDisp = function(disp, suppressScrollEvent) { this.emit('scroll', this.ydisp); } - this.queueRefresh(0, this.rows - 1); + this.refresh(0, this.rows - 1); }; /** @@ -1239,7 +1229,7 @@ Terminal.prototype.innerWrite = function() { this.parser.parse(data); this.updateRange(this.y); - this.queueRefresh(this.refreshStart, this.refreshEnd); + this.refresh(this.refreshStart, this.refreshEnd); } if (this.writeBuffer.length > 0) { // Allow renderer to catch up before processing the next batch @@ -1824,7 +1814,7 @@ Terminal.prototype.resize = function(x, y) { this.charMeasure.measure(); - this.queueRefresh(0, this.rows - 1); + this.refresh(0, this.rows - 1); this.normal = null; @@ -1956,7 +1946,7 @@ Terminal.prototype.clear = function() { for (var i = 1; i < this.rows; i++) { this.lines.push(this.blankLine()); } - this.queueRefresh(0, this.rows - 1); + this.refresh(0, this.rows - 1); this.emit('scroll', this.ydisp); }; @@ -2094,7 +2084,7 @@ Terminal.prototype.reset = function() { var customKeydownHandler = this.customKeydownHandler; Terminal.call(this, this.options); this.customKeydownHandler = customKeydownHandler; - this.queueRefresh(0, this.rows - 1); + this.refresh(0, this.rows - 1); this.viewport.syncScrollArea(); }; From 20f22fb658b0ddaf5a0dbf05b6517a51bf3f3136 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Feb 2017 11:18:44 -0800 Subject: [PATCH 092/211] Convert flags to enum --- src/Renderer.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/Renderer.ts b/src/Renderer.ts index d99f9be4..9b6234ca 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -11,16 +11,15 @@ import { ITerminal } from './Interfaces'; */ const MAX_REFRESH_FRAME_SKIP = 5; -// TODO: Convert flags to number enum /** - * Flags used to render terminal text properly + * Flags used to render terminal text properly. */ -const FLAGS = { - BOLD: 1, - UNDERLINE: 2, - BLINK: 4, - INVERSE: 8, - INVISIBLE: 16 +enum FLAGS { + BOLD = 1, + UNDERLINE = 2, + BLINK = 4, + INVERSE = 8, + INVISIBLE = 16 }; let brokenBold: boolean = null; @@ -118,9 +117,6 @@ export class Renderer { * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) */ private _refresh(start: number, end: number): void { - // TODO: Use fat arrow functions for callbacks to avoid `self` - let self = this; - let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement; // If this is a big refresh, remove the terminal rows from the DOM for faster calculations From cc78fdd63c6a3b33247d83d35c83efa0f8f4acd1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Feb 2017 11:19:54 -0800 Subject: [PATCH 093/211] Hold on to renderer if a reset occurs --- src/xterm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 0229df90..6204d135 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -208,7 +208,8 @@ function Terminal(options) { this.inputHandler = new InputHandler(this); this.parser = new Parser(this.inputHandler, this); - this.renderer = null; + // Reuse renderer if the Terminal is being recreated via a Terminal.reset call. + this.renderer = this.renderer || null; // user input states this.writeBuffer = []; From 833eb5216bad3096463f7bda675582a0b9184d3f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Feb 2017 11:50:52 -0800 Subject: [PATCH 094/211] Add null check on Terminal.element Since the Terminal can be used now before being attached, we should check element on destroy. Related to #266 --- src/xterm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 6204d135..664d1812 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1045,7 +1045,7 @@ Terminal.prototype.destroy = function() { this._events = {}; this.handler = function() {}; this.write = function() {}; - if (this.element.parentNode) { + if (this.element && this.element.parentNode) { this.element.parentNode.removeChild(this.element); } //this.emit('close'); From e58a6975da4cd9faa56a8089641f9440d6545f54 Mon Sep 17 00:00:00 2001 From: Bill Church Date: Wed, 1 Feb 2017 16:41:47 -0500 Subject: [PATCH 095/211] Update README.md Adding WebSSH2 to real-word uses --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c251da48..fe75e6bc 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE. - [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams. - [**CoderPad**](https://coderpad.io): Online interviewing platform for programmers. Run code in many programming languages, with results displayed by `xterm.js`. +- [**WebSSH2**](https://github.com/billchurch/WebSSH2): A web based SSH2 client using `xterm.js`, socket.io, and ssh2. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From ee0d6b453354e2beb68f541ce2b84925e7ca530f Mon Sep 17 00:00:00 2001 From: Lucian Buzzo Date: Sun, 5 Feb 2017 12:45:55 +0000 Subject: [PATCH 096/211] Fixed issue where terminal would become unusable if NaN values are sent to resize method. --- src/xterm.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xterm.js b/src/xterm.js index 560db5fe..0a8c2a1c 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1973,6 +1973,10 @@ Terminal.prototype.error = function() { * @param {number} y The number of rows to resize to. */ Terminal.prototype.resize = function(x, y) { + if (Number.isNaN(x) || Number.isNaN(y)) { + return; + } + var line , el , i From 56b541b44f74e5bec5c2a0dfe4b77d73cf5d94c8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Feb 2017 13:56:52 -0800 Subject: [PATCH 097/211] Add description to package.json This should fix the ugly broken markdown at the top of npm --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index c05d97f2..8e81c204 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "xterm", + "description": "Full xterm terminal, in your browser", "version": "2.2.3", "ignore": [ "demo", From e79e67c3ce974f08dabc9836c97fe11b80ad79f5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 7 Feb 2017 21:17:47 -0800 Subject: [PATCH 098/211] Disable escape sequence tests on windows --- src/test/escape-sequences-test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/escape-sequences-test.js b/src/test/escape-sequences-test.js index f35bc00a..49f62341 100644 --- a/src/test/escape-sequences-test.js +++ b/src/test/escape-sequences-test.js @@ -1,9 +1,15 @@ var glob = require('glob'); var fs = require('fs'); +var os = require('os'); var pty = require('node-pty'); var sleep = require('sleep'); var Terminal = require('../xterm'); +if (os.platform() === 'win32') { + // Skip tests on Windows since pty.open isn't supported + return; +} + var CONSOLE_LOG = console.log; // expect files need terminal at 80x25! From 2207d356f251f45e0b0027d858f0edbc15219840 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 11:11:52 -0800 Subject: [PATCH 099/211] Initial linkify implementation Part of 455 --- src/Linkifier.ts | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ src/xterm.css | 4 +++ src/xterm.js | 11 +++++++ 3 files changed, 98 insertions(+) create mode 100644 src/Linkifier.ts diff --git a/src/Linkifier.ts b/src/Linkifier.ts new file mode 100644 index 00000000..6eaf82cd --- /dev/null +++ b/src/Linkifier.ts @@ -0,0 +1,83 @@ +/** + * The time to wait after a row is changed before it is linkified. This prevents + * the costly operation of searching every row multiple times, pntentially a + * huge aount of times. + */ +const TIME_BEFORE_LINKIFY = 200; + +const badUrlRegex = /https?:\/\/(\/[\/\\w\.-]*)*/; + +const protocolClause = '(https?:\\/\\/)'; +const domainCharacterSet = '[\\da-z\\.-]+'; +const negatedDomainCharacterSet = '[^\\da-z\\.-]+'; +const domainBodyClause = '(' + domainCharacterSet + ')'; +const tldClause = '([a-z\\.]{2,6})'; +const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; +const portClause = '(:\\d{1,5})'; +const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?'; +const pathClause = '(\\/[\\/\\w\\.-]*)*'; +const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; +const bodyClause = hostClause + pathClause; +const start = '(?:^|' + negatedDomainCharacterSet + ')('; +const end = ')($|' + negatedPathCharacterSet + ')'; +const lenientUrlClause = start + protocolClause + '?' + bodyClause + end; +const strictUrlClause = start + protocolClause + bodyClause + end; +const lenientUrlRegex = new RegExp(lenientUrlClause); +const strictUrlRegex = new RegExp(strictUrlClause); + +export type LinkHandler = (uri: string) => void; + +export class Linkifier { + private _rows: HTMLElement[]; + private _rowTimeoutIds: number[]; + private _webLinkHandler: LinkHandler; + + constructor(rows: HTMLElement[]) { + this._rows = rows; + this._rowTimeoutIds = []; + } + + /** + * Queues a row for linkification. + * @param {number} rowIndex The index of the row to linkify. + */ + public linkifyRow(rowIndex: number): void { + const timeoutId = this._rowTimeoutIds[rowIndex]; + if (timeoutId) { + clearTimeout(timeoutId); + } + this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), TIME_BEFORE_LINKIFY); + } + + public attachWebLinkHandler(handler: LinkHandler): void { + this._webLinkHandler = handler; + } + + /** + * Linkifies a row. + * @param {number} rowIndex The index of the row to linkify. + */ + private _linkifyRow(rowIndex: number): void { + const rowHtml = this._rows[rowIndex].innerHTML; + const uri = this._findLinkMatch(rowHtml); + if (uri) { + const link = '' + uri + ''; + const newHtml = rowHtml.replace(uri, link); + this._rows[rowIndex].innerHTML = newHtml; + console.log(this._rows[rowIndex].innerHTML); + } + } + + /** + * Finds a link match in a piece of HTML. + * @param {string} html The HTML to search. + * @return The matching URI or null if not found. + */ + private _findLinkMatch(html): string { + const match = html.match(strictUrlRegex); + if (!match || match.length === 0) { + return null; + } + return match[1]; + } +} diff --git a/src/xterm.css b/src/xterm.css index 27638e14..3075bba4 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -71,6 +71,10 @@ resize: none; } +.terminal a { + color: inherit; +} + .terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { background-color: #fff; color: #000; diff --git a/src/xterm.js b/src/xterm.js index b2740683..26ed1f70 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -19,6 +19,7 @@ import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; import { Parser } from './Parser'; import { Renderer } from './Renderer'; +import { Linkifier } from './Linkifier'; import { CharMeasure } from './utils/CharMeasure'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -210,6 +211,7 @@ function Terminal(options) { this.parser = new Parser(this.inputHandler, this); // Reuse renderer if the Terminal is being recreated via a Terminal.reset call. this.renderer = this.renderer || null; + this.linkifier = this.linkifier || null;; // user input states this.writeBuffer = []; @@ -607,6 +609,7 @@ Terminal.prototype.open = function(parent) { this.rowContainer.classList.add('xterm-rows'); this.element.appendChild(this.rowContainer); this.children = []; + this.linkifier = new Linkifier(this.children); // Create the container that will hold helpers like the textarea for // capturing DOM Events. Then produce the helpers. @@ -1060,6 +1063,14 @@ Terminal.prototype.destroy = function() { Terminal.prototype.refresh = function(start, end) { if (this.renderer) { this.renderer.queueRefresh(start, end); + + // TODO: DO this better + if (!this.linkifier) { + return; + } + for (let i = start; i <= end; i++) { + this.linkifier.linkifyRow(i); + } } }; From c48388af14f586a961e42d94e219f4fb217241d2 Mon Sep 17 00:00:00 2001 From: Aleksandr Andrienko Date: Wed, 8 Feb 2017 23:15:54 +0200 Subject: [PATCH 100/211] Remove excess library. Tsify lib used for browserify typescript sources. But folder /lib consist of js files has already compiled from TypeScript sources (by gulp task tsc). So Tsify library does nothing in this case. Signed-off-by: Aleksandr Andrienko --- gulpfile.js | 2 -- package.json | 1 - 2 files changed, 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 144b8831..ff4a7438 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,7 +7,6 @@ const sorcery = require('sorcery'); const source = require('vinyl-source-stream'); const sourcemaps = require('gulp-sourcemaps'); const ts = require('gulp-typescript'); -const tsify = require('tsify'); let buildDir = process.env.BUILD_DIR || 'build'; @@ -53,7 +52,6 @@ gulp.task('browserify', ['tsc'], function() { packageCache: {} }; let bundleStream = browserify(browserifyOptions) - .plugin(tsify) .bundle() .pipe(source('xterm.js')) .pipe(buffer()) diff --git a/package.json b/package.json index 8e81c204..0ce6ca36 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "nodemon": "1.10.2", "sleep": "^3.0.1", "sorcery": "^0.10.0", - "tsify": "^3.0.0", "tslint": "^4.0.2", "typescript": "^2.0.3", "vinyl-buffer": "^1.0.0", From a489037ec407f119a2038a248282a042bb499311 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 13:50:36 -0800 Subject: [PATCH 101/211] Improve node insertion, support custom link handlers --- src/Linkifier.ts | 129 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 120 insertions(+), 9 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 6eaf82cd..64be3947 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -5,8 +5,6 @@ */ const TIME_BEFORE_LINKIFY = 200; -const badUrlRegex = /https?:\/\/(\/[\/\\w\.-]*)*/; - const protocolClause = '(https?:\\/\\/)'; const domainCharacterSet = '[\\da-z\\.-]+'; const negatedDomainCharacterSet = '[^\\da-z\\.-]+'; @@ -49,8 +47,10 @@ export class Linkifier { this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), TIME_BEFORE_LINKIFY); } + // TODO: Support local links public attachWebLinkHandler(handler: LinkHandler): void { this._webLinkHandler = handler; + // TODO: Refresh links if a handler is attached? } /** @@ -60,24 +60,135 @@ export class Linkifier { private _linkifyRow(rowIndex: number): void { const rowHtml = this._rows[rowIndex].innerHTML; const uri = this._findLinkMatch(rowHtml); - if (uri) { - const link = '' + uri + ''; - const newHtml = rowHtml.replace(uri, link); - this._rows[rowIndex].innerHTML = newHtml; - console.log(this._rows[rowIndex].innerHTML); + if (!uri) { + return; + } + + // Iterate over nodes as we want to consider text nodes + const nodes = this._rows[rowIndex].childNodes; + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + const searchIndex = node.textContent.indexOf(uri); + if (searchIndex >= 0) { + if (node.childNodes.length > 0) { + // This row has already been linkified + return; + } + + console.log('found uri: ' + uri); + const linkElement = this._createAnchorElement(uri); + // TODO: Check if childNodes check is needed + if (node.textContent.trim().length === uri.length) { + // Matches entire string + console.log('match entire string'); + if (node.nodeType === Node.TEXT_NODE) { + console.log('text node'); + this._replaceNode(node, linkElement); + } else { + console.log('element'); + const element = (node); + element.innerHTML = ''; + element.appendChild(linkElement); + } + } else { + // Matches part of string + console.log('part of string'); + this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); + } + } + // Continue searching in case multiple URIs exist on a single + // const link = '' + uri + ''; + // const newHtml = rowHtml.replace(uri, link); + // this._rows[rowIndex].innerHTML = newHtml; } } /** * Finds a link match in a piece of HTML. * @param {string} html The HTML to search. - * @return The matching URI or null if not found. + * @return {string} The matching URI or null if not found. */ - private _findLinkMatch(html): string { + private _findLinkMatch(html: string): string { const match = html.match(strictUrlRegex); if (!match || match.length === 0) { return null; } return match[1]; } + + /** + * Creates a link anchor element. + * @param {string} uri The uri of the link. + * @return {HTMLAnchorElement} The link. + */ + private _createAnchorElement(uri: string): HTMLAnchorElement { + const element = document.createElement('a'); + element.textContent = uri; + // Force link on another tab so work is not lost + element.target = '_blank'; + if (this._webLinkHandler) { + element.href = '#'; + element.addEventListener('click', () => this._webLinkHandler(uri)); + } else { + element.href = uri; + } + return element; + } + + /** + * Replace a node with 1 or more other nodes. + * @param {Node} oldNode The node to replace. + * @param {Node[]} newNodes The new nodes to insert in order. + */ + private _replaceNode(oldNode: Node, ...newNodes: Node[]): void { + const parent = oldNode.parentNode; + for (let i = 0; i < newNodes.length; i++) { + parent.insertBefore(newNodes[i], oldNode); + } + parent.removeChild(oldNode); + } + + /** + * Replace a substring within a node with a new node. + * @param {Node} targetNode The target node. + * @param {Node} newNode The new node to insert. + * @param {string} substring The substring to replace. + * @param {number} substringIndex The index of the substring within the string. + */ + private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): void { + let node = targetNode; + if (node.nodeType !== Node.TEXT_NODE) { + node = node.childNodes[0]; + } + // The targetNode will be either a text node or a . The targetNode is + // assumed to have no children. In either case, the targetNode's text node + // must be split into 2 text nodes surrounding the newNode. + if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) { + throw new Error('targetNode must be a text node or only contain a single text node'); + } + + const fullText = node.textContent; + + if (substringIndex === 0) { + // Replace with + console.log('Replace with '); + const rightText = fullText.substring(substring.length); + const rightTextNode = document.createTextNode(rightText); + this._replaceNode(node, newNode, rightTextNode); + } else if (substringIndex === targetNode.textContent.length - substring.length) { + // Replace with + console.log('Replace with '); + const leftText = fullText.substring(0, substringIndex); + const leftTextNode = document.createTextNode(leftText); + this._replaceNode(node, leftTextNode, newNode); + } else { + // Replace with + console.log('Replace with '); + const leftText = fullText.substring(0, substringIndex); + const leftTextNode = document.createTextNode(leftText); + const rightText = fullText.substring(substringIndex + substring.length); + const rightTextNode = document.createTextNode(rightText); + this._replaceNode(node, leftTextNode, newNode, rightTextNode); + } + } } From 0f3ee21d9d8a53622b7c640d4dfe5909fd3839bb Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 14:13:30 -0800 Subject: [PATCH 102/211] Enable custom http link handlers --- src/Linkifier.ts | 30 +++++++++++++----------------- src/xterm.css | 6 ++++++ src/xterm.js | 10 ++++++++++ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 64be3947..adb96566 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -28,7 +28,7 @@ export type LinkHandler = (uri: string) => void; export class Linkifier { private _rows: HTMLElement[]; private _rowTimeoutIds: number[]; - private _webLinkHandler: LinkHandler; + private _hypertextLinkHandler: LinkHandler; constructor(rows: HTMLElement[]) { this._rows = rows; @@ -48,9 +48,8 @@ export class Linkifier { } // TODO: Support local links - public attachWebLinkHandler(handler: LinkHandler): void { - this._webLinkHandler = handler; - // TODO: Refresh links if a handler is attached? + public attachHypertextLinkHandler(handler: LinkHandler): void { + this._hypertextLinkHandler = handler; } /** @@ -96,10 +95,6 @@ export class Linkifier { this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); } } - // Continue searching in case multiple URIs exist on a single - // const link = '' + uri + ''; - // const newHtml = rowHtml.replace(uri, link); - // this._rows[rowIndex].innerHTML = newHtml; } } @@ -124,13 +119,12 @@ export class Linkifier { private _createAnchorElement(uri: string): HTMLAnchorElement { const element = document.createElement('a'); element.textContent = uri; - // Force link on another tab so work is not lost - element.target = '_blank'; - if (this._webLinkHandler) { - element.href = '#'; - element.addEventListener('click', () => this._webLinkHandler(uri)); + if (this._hypertextLinkHandler) { + element.addEventListener('click', () => this._hypertextLinkHandler(uri)); } else { element.href = uri; + // Force link on another tab so work is not lost + element.target = '_blank'; } return element; } @@ -150,7 +144,8 @@ export class Linkifier { /** * Replace a substring within a node with a new node. - * @param {Node} targetNode The target node. + * @param {Node} targetNode The target node; either a text node or a + * containing a single text node. * @param {Node} newNode The new node to insert. * @param {string} substring The substring to replace. * @param {number} substringIndex The index of the substring within the string. @@ -160,9 +155,10 @@ export class Linkifier { if (node.nodeType !== Node.TEXT_NODE) { node = node.childNodes[0]; } - // The targetNode will be either a text node or a . The targetNode is - // assumed to have no children. In either case, the targetNode's text node - // must be split into 2 text nodes surrounding the newNode. + + // The targetNode will be either a text node or a . The text node + // (targetNode or its only-child) needs to be replaced with newNode plus new + // text nodes potentially on either side. if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) { throw new Error('targetNode must be a text node or only contain a single text node'); } diff --git a/src/xterm.css b/src/xterm.css index 3075bba4..43f2594c 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -73,6 +73,12 @@ .terminal a { color: inherit; + /* Feature underline on links even if they have no href */ + text-decoration: underline; +} + +.terminal a:hover { + cursor: pointer; } .terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { diff --git a/src/xterm.js b/src/xterm.js index 26ed1f70..f858af31 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1274,6 +1274,16 @@ Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) { this.customKeydownHandler = customKeydownHandler; } +// TODO: Doc +Terminal.prototype.attachHypertextLinkHandler = function(handler) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); + } + this.linkifier.attachHypertextLinkHandler(handler); + // Refresh to force links to refresh + this.refresh(0, this.rows - 1); +} + /** * Handle a keydown event * Key Resources: From 8dd11f558795de9951ee720eb5902cbfcefcc2c7 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 8 Feb 2017 22:24:56 +0000 Subject: [PATCH 103/211] Bump version to 2.3.0 Signed-off-by: Paris Kasidiaris --- AUTHORS | 7 + bower.json | 2 +- dist/addons/attach/attach.js | 216 +- dist/addons/fit/fit.js | 110 +- dist/addons/fullscreen/fullscreen.js | 84 +- dist/addons/linkify/linkify.js | 344 +- dist/addons/terminado/terminado.js | 231 +- dist/xterm.css | 44 +- dist/xterm.js | 8786 +++++++++++--------------- dist/xterm.js.map | 2 +- package.json | 2 +- 11 files changed, 4335 insertions(+), 5493 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4fa37cd6..c3e3a97f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,7 +7,10 @@ Anton Skshidlevsky Anton Yurovskykh Austin Robertson ayapi +Ben Hall Benjamin Fischer +Bill Church +Bob Reid bottleofwater Carson Anderson Christian Budde Christensen @@ -22,13 +25,17 @@ Ian Lewis imoses Jean Bruenn Jörg Breitbart +Lucian Buzzo Maël Nison Mikko Karvonen Paris Kasidiaris Paris Kasidiaris runarberg +Saswat Das Shuanglei Tao Steven Silvester Thanasis Daglis Tine Jozelj +Tyler Jewell +Vincent Woo YuviPanda diff --git a/bower.json b/bower.json index 47b73b39..a7b2929a 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "xterm.js", - "version": "2.2.3", + "version": "2.3.0", "ignore": ["demo", "test", ".gitignore"], "main": [ "dist/xterm.js", diff --git a/dist/addons/attach/attach.js b/dist/addons/attach/attach.js index 8cf759ae..c2a7989b 100644 --- a/dist/addons/attach/attach.js +++ b/dist/addons/attach/attach.js @@ -3,112 +3,124 @@ * @module xterm/addons/attach/attach * @license MIT */ + (function (attach) { - if (typeof exports === 'object' && typeof module === 'object') { - /* - * CommonJS environment - */ - module.exports = attach(require('../../xterm')); - } - else if (typeof define == 'function') { - /* - * Require.js is available - */ - define(['../../xterm'], attach); - } - else { - /* - * Plain browser environment - */ - attach(window.Terminal); - } + if (typeof exports === 'object' && typeof module === 'object') { + /* + * CommonJS environment + */ + module.exports = attach(require('../../xterm')); + } else if (typeof define == 'function') { + /* + * Require.js is available + */ + define(['../../xterm'], attach); + } else { + /* + * Plain browser environment + */ + attach(window.Terminal); + } })(function (Xterm) { - 'use strict'; - var exports = {}; - /** - * Attaches the given terminal to the given socket. - * - * @param {Xterm} term - The terminal to be attached to the given socket. - * @param {WebSocket} socket - The socket to attach the current terminal. - * @param {boolean} bidirectional - Whether the terminal should send data - * to the socket as well. - * @param {boolean} buffered - Whether the rendering of incoming data - * should happen instantly or at a maximum - * frequency of 1 rendering per 10ms. - */ - exports.attach = function (term, socket, bidirectional, buffered) { - bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; - term.socket = socket; - term._flushBuffer = function () { - term.write(term._attachSocketBuffer); - term._attachSocketBuffer = null; - clearTimeout(term._attachSocketBufferTimer); - term._attachSocketBufferTimer = null; - }; - term._pushToBuffer = function (data) { - if (term._attachSocketBuffer) { - term._attachSocketBuffer += data; - } - else { - term._attachSocketBuffer = data; - setTimeout(term._flushBuffer, 10); - } - }; - term._getMessage = function (ev) { - if (buffered) { - term._pushToBuffer(ev.data); - } - else { - term.write(ev.data); - } - }; - term._sendData = function (data) { - socket.send(data); - }; - socket.addEventListener('message', term._getMessage); - if (bidirectional) { - term.on('data', term._sendData); - } - socket.addEventListener('close', term.detach.bind(term, socket)); - socket.addEventListener('error', term.detach.bind(term, socket)); + 'use strict'; + + var exports = {}; + + /** + * Attaches the given terminal to the given socket. + * + * @param {Xterm} term - The terminal to be attached to the given socket. + * @param {WebSocket} socket - The socket to attach the current terminal. + * @param {boolean} bidirectional - Whether the terminal should send data + * to the socket as well. + * @param {boolean} buffered - Whether the rendering of incoming data + * should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. + */ + exports.attach = function (term, socket, bidirectional, buffered) { + bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; + term.socket = socket; + + term._flushBuffer = function () { + term.write(term._attachSocketBuffer); + term._attachSocketBuffer = null; + clearTimeout(term._attachSocketBufferTimer); + term._attachSocketBufferTimer = null; }; - /** - * Detaches the given terminal from the given socket - * - * @param {Xterm} term - The terminal to be detached from the given socket. - * @param {WebSocket} socket - The socket from which to detach the current - * terminal. - */ - exports.detach = function (term, socket) { - term.off('data', term._sendData); - socket = (typeof socket == 'undefined') ? term.socket : socket; - if (socket) { - socket.removeEventListener('message', term._getMessage); - } - delete term.socket; + + term._pushToBuffer = function (data) { + if (term._attachSocketBuffer) { + term._attachSocketBuffer += data; + } else { + term._attachSocketBuffer = data; + setTimeout(term._flushBuffer, 10); + } }; - /** - * Attaches the current terminal to the given socket - * - * @param {WebSocket} socket - The socket to attach the current terminal. - * @param {boolean} bidirectional - Whether the terminal should send data - * to the socket as well. - * @param {boolean} buffered - Whether the rendering of incoming data - * should happen instantly or at a maximum - * frequency of 1 rendering per 10ms. - */ - Xterm.prototype.attach = function (socket, bidirectional, buffered) { - return exports.attach(this, socket, bidirectional, buffered); + + term._getMessage = function (ev) { + if (buffered) { + term._pushToBuffer(ev.data); + } else { + term.write(ev.data); + } }; - /** - * Detaches the current terminal from the given socket. - * - * @param {WebSocket} socket - The socket from which to detach the current - * terminal. - */ - Xterm.prototype.detach = function (socket) { - return exports.detach(this, socket); + + term._sendData = function (data) { + socket.send(data); }; - return exports; + + socket.addEventListener('message', term._getMessage); + + if (bidirectional) { + term.on('data', term._sendData); + } + + socket.addEventListener('close', term.detach.bind(term, socket)); + socket.addEventListener('error', term.detach.bind(term, socket)); + }; + + /** + * Detaches the given terminal from the given socket + * + * @param {Xterm} term - The terminal to be detached from the given socket. + * @param {WebSocket} socket - The socket from which to detach the current + * terminal. + */ + exports.detach = function (term, socket) { + term.off('data', term._sendData); + + socket = (typeof socket == 'undefined') ? term.socket : socket; + + if (socket) { + socket.removeEventListener('message', term._getMessage); + } + + delete term.socket; + }; + + /** + * Attaches the current terminal to the given socket + * + * @param {WebSocket} socket - The socket to attach the current terminal. + * @param {boolean} bidirectional - Whether the terminal should send data + * to the socket as well. + * @param {boolean} buffered - Whether the rendering of incoming data + * should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. + */ + Xterm.prototype.attach = function (socket, bidirectional, buffered) { + return exports.attach(this, socket, bidirectional, buffered); + }; + + /** + * Detaches the current terminal from the given socket. + * + * @param {WebSocket} socket - The socket from which to detach the current + * terminal. + */ + Xterm.prototype.detach = function (socket) { + return exports.detach(this, socket); + }; + + return exports; }); -//# sourceMappingURL=attach.js.map \ No newline at end of file diff --git a/dist/addons/fit/fit.js b/dist/addons/fit/fit.js index f3a33960..cacd9202 100644 --- a/dist/addons/fit/fit.js +++ b/dist/addons/fit/fit.js @@ -10,50 +10,72 @@ * @module xterm/addons/fit/fit * @license MIT */ + (function (fit) { - if (typeof exports === 'object' && typeof module === 'object') { - /* - * CommonJS environment - */ - module.exports = fit(require('../../xterm')); - } - else if (typeof define == 'function') { - /* - * Require.js is available - */ - define(['../../xterm'], fit); - } - else { - /* - * Plain browser environment - */ - fit(window.Terminal); - } + if (typeof exports === 'object' && typeof module === 'object') { + /* + * CommonJS environment + */ + module.exports = fit(require('../../xterm')); + } else if (typeof define == 'function') { + /* + * Require.js is available + */ + define(['../../xterm'], fit); + } else { + /* + * Plain browser environment + */ + fit(window.Terminal); + } })(function (Xterm) { - var exports = {}; - exports.proposeGeometry = function (term) { - var parentElementStyle = window.getComputedStyle(term.element.parentElement), parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), elementStyle = window.getComputedStyle(term.element), elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')), elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')), availableHeight = parentElementHeight - elementPaddingVer, availableWidth = parentElementWidth - elementPaddingHor, container = term.rowContainer, subjectRow = term.rowContainer.firstElementChild, contentBuffer = subjectRow.innerHTML, characterHeight, rows, characterWidth, cols, geometry; - subjectRow.style.display = 'inline'; - subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace - characterWidth = subjectRow.getBoundingClientRect().width; - subjectRow.style.display = ''; // Revert style before calculating height, since they differ. - characterHeight = parseInt(subjectRow.offsetHeight); - subjectRow.innerHTML = contentBuffer; - rows = parseInt(availableHeight / characterHeight); - cols = parseInt(availableWidth / characterWidth); - geometry = { cols: cols, rows: rows }; - return geometry; - }; - exports.fit = function (term) { - var geometry = exports.proposeGeometry(term); - term.resize(geometry.cols, geometry.rows); - }; - Xterm.prototype.proposeGeometry = function () { - return exports.proposeGeometry(this); - }; - Xterm.prototype.fit = function () { - return exports.fit(this); - }; - return exports; + var exports = {}; + + exports.proposeGeometry = function (term) { + var parentElementStyle = window.getComputedStyle(term.element.parentElement), + parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), + parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), + elementStyle = window.getComputedStyle(term.element), + elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')), + elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')), + availableHeight = parentElementHeight - elementPaddingVer, + availableWidth = parentElementWidth - elementPaddingHor, + container = term.rowContainer, + subjectRow = term.rowContainer.firstElementChild, + contentBuffer = subjectRow.innerHTML, + characterHeight, + rows, + characterWidth, + cols, + geometry; + + subjectRow.style.display = 'inline'; + subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace + characterWidth = subjectRow.getBoundingClientRect().width; + subjectRow.style.display = ''; // Revert style before calculating height, since they differ. + characterHeight = parseInt(subjectRow.offsetHeight); + subjectRow.innerHTML = contentBuffer; + + rows = parseInt(availableHeight / characterHeight); + cols = parseInt(availableWidth / characterWidth); + + geometry = {cols: cols, rows: rows}; + return geometry; + }; + + exports.fit = function (term) { + var geometry = exports.proposeGeometry(term); + + term.resize(geometry.cols, geometry.rows); + }; + + Xterm.prototype.proposeGeometry = function () { + return exports.proposeGeometry(this); + }; + + Xterm.prototype.fit = function () { + return exports.fit(this); + }; + + return exports; }); -//# sourceMappingURL=fit.js.map \ No newline at end of file diff --git a/dist/addons/fullscreen/fullscreen.js b/dist/addons/fullscreen/fullscreen.js index a3227217..e8e34ea3 100644 --- a/dist/addons/fullscreen/fullscreen.js +++ b/dist/addons/fullscreen/fullscreen.js @@ -4,47 +4,47 @@ * @license MIT */ (function (fullscreen) { - if (typeof exports === 'object' && typeof module === 'object') { - /* - * CommonJS environment - */ - module.exports = fullscreen(require('../../xterm')); - } - else if (typeof define == 'function') { - /* - * Require.js is available - */ - define(['../../xterm'], fullscreen); - } - else { - /* - * Plain browser environment - */ - fullscreen(window.Terminal); - } -})(function (Xterm) { - var exports = {}; - /** - * Toggle the given terminal's fullscreen mode. - * @param {Xterm} term - The terminal to toggle full screen mode - * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false) + if (typeof exports === 'object' && typeof module === 'object') { + /* + * CommonJS environment */ - exports.toggleFullScreen = function (term, fullscreen) { - var fn; - if (typeof fullscreen == 'undefined') { - fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add'; - } - else if (!fullscreen) { - fn = 'remove'; - } - else { - fn = 'add'; - } - term.element.classList[fn]('fullscreen'); - }; - Xterm.prototype.toggleFullscreen = function (fullscreen) { - exports.toggleFullScreen(this, fullscreen); - }; - return exports; + module.exports = fullscreen(require('../../xterm')); + } else if (typeof define == 'function') { + /* + * Require.js is available + */ + define(['../../xterm'], fullscreen); + } else { + /* + * Plain browser environment + */ + fullscreen(window.Terminal); + } +})(function (Xterm) { + var exports = {}; + + /** + * Toggle the given terminal's fullscreen mode. + * @param {Xterm} term - The terminal to toggle full screen mode + * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false) + */ + exports.toggleFullScreen = function (term, fullscreen) { + var fn; + + if (typeof fullscreen == 'undefined') { + fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add'; + } else if (!fullscreen) { + fn = 'remove'; + } else { + fn = 'add'; + } + + term.element.classList[fn]('fullscreen'); + }; + + Xterm.prototype.toggleFullscreen = function (fullscreen) { + exports.toggleFullScreen(this, fullscreen); + }; + + return exports; }); -//# sourceMappingURL=fullscreen.js.map \ No newline at end of file diff --git a/dist/addons/linkify/linkify.js b/dist/addons/linkify/linkify.js index d3a6933d..d2391026 100644 --- a/dist/addons/linkify/linkify.js +++ b/dist/addons/linkify/linkify.js @@ -3,163 +3,205 @@ * @module xterm/addons/linkify/linkify * @license MIT */ + (function (linkify) { - if (typeof exports === 'object' && typeof module === 'object') { - /* - * CommonJS environment - */ - module.exports = linkify(require('../../xterm')); - } - else if (typeof define == 'function') { - /* - * Require.js is available - */ - define(['../../xterm'], linkify); - } - else { - /* - * Plain browser environment - */ - linkify(window.Terminal); - } + if (typeof exports === 'object' && typeof module === 'object') { + /* + * CommonJS environment + */ + module.exports = linkify(require('../../xterm')); + } else if (typeof define == 'function') { + /* + * Require.js is available + */ + define(['../../xterm'], linkify); + } else { + /* + * Plain browser environment + */ + linkify(window.Terminal); + } })(function (Xterm) { - 'use strict'; - var exports = {}, protocolClause = '(https?:\\/\\/)', domainCharacterSet = '[\\da-z\\.-]+', negatedDomainCharacterSet = '[^\\da-z\\.-]+', domainBodyClause = '(' + domainCharacterSet + ')', tldClause = '([a-z\\.]{2,6})', ipClause = '((\\d{1,3}\\.){3}\\d{1,3})', portClause = '(:\\d{1,5})', hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?', pathClause = '(\\/[\\/\\w\\.-]*)*', negatedPathCharacterSet = '[^\\/\\w\\.-]+', bodyClause = hostClause + pathClause, start = '(?:^|' + negatedDomainCharacterSet + ')(', end = ')($|' + negatedPathCharacterSet + ')', lenientUrlClause = start + protocolClause + '?' + bodyClause + end, strictUrlClause = start + protocolClause + bodyClause + end, lenientUrlRegex = new RegExp(lenientUrlClause), strictUrlRegex = new RegExp(strictUrlClause); + 'use strict'; + + var exports = {}, + protocolClause = '(https?:\\/\\/)', + domainCharacterSet = '[\\da-z\\.-]+', + negatedDomainCharacterSet = '[^\\da-z\\.-]+', + domainBodyClause = '(' + domainCharacterSet + ')', + tldClause = '([a-z\\.]{2,6})', + ipClause = '((\\d{1,3}\\.){3}\\d{1,3})', + portClause = '(:\\d{1,5})', + hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?', + pathClause = '(\\/[\\/\\w\\.-]*)*', + negatedPathCharacterSet = '[^\\/\\w\\.-]+', + bodyClause = hostClause + pathClause, + start = '(?:^|' + negatedDomainCharacterSet + ')(', + end = ')($|' + negatedPathCharacterSet + ')', + lenientUrlClause = start + protocolClause + '?' + bodyClause + end, + strictUrlClause = start + protocolClause + bodyClause + end, + lenientUrlRegex = new RegExp(lenientUrlClause), + strictUrlRegex = new RegExp(strictUrlClause); + + /** + * Converts all valid URLs found in the given terminal line into + * hyperlinks. The terminal line can be either the HTML element itself + * or the index of the termina line in the children of the terminal + * rows container. + * + * @param {Xterm} terminal - The terminal that owns the given line. + * @param {number|HTMLDivElement} line - The terminal line that should get + * "linkified". + * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is + * false, the regex requires a protocol clause. Defaults to true. + * @param {string} target - Sets target="" attribute with value provided to links. + * Default doesn't set target attribute + * @emits linkify + * @emits linkify:line + */ + exports.linkifyTerminalLine = function (terminal, line, lenient, target) { + if (typeof line == 'number') { + line = terminal.rowContainer.children[line]; + } else if (! (line instanceof HTMLDivElement)) { + var message = 'The "line" argument should be either a number'; + message += ' or an HTMLDivElement'; + + throw new TypeError(message); + } + + if (typeof target === 'undefined') { + target = ''; + } else { + target = 'target="' + target + '"'; + } + + var buffer = document.createElement('span'), + nodes = line.childNodes; + + for (var j=0; j' + url + '', + newHTML = nodeHTML.replace(url, link); + + line.innerHTML = line.innerHTML.replace(nodeHTML, newHTML); + } + /** - * Converts all valid URLs found in the given terminal line into - * hyperlinks. The terminal line can be either the HTML element itself - * or the index of the termina line in the children of the terminal - * rows container. + * This event gets emitted when conversion of all URL susbtrings + * to HTML anchor elements (links) has finished, for a specific + * line of the current Xterm instance. * - * @param {Xterm} terminal - The terminal that owns the given line. - * @param {number|HTMLDivElement} line - The terminal line that should get - * "linkified". - * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is - * false, the regex requires a protocol clause. Defaults to true. - * @param {string} target - Sets target="" attribute with value provided to links. - * Default doesn't set target attribute - * @emits linkify - * @emits linkify:line + * @event linkify:line */ - exports.linkifyTerminalLine = function (terminal, line, lenient, target) { - if (typeof line == 'number') { - line = terminal.rowContainer.children[line]; - } - else if (!(line instanceof HTMLDivElement)) { - var message = 'The "line" argument should be either a number'; - message += ' or an HTMLDivElement'; - throw new TypeError(message); - } - if (typeof target === 'undefined') { - target = ''; - } - else { - target = 'target="' + target + '"'; - } - var buffer = document.createElement('span'), nodes = line.childNodes; - for (var j = 0; j < nodes.length; j++) { - var node = nodes[j], match; - /** - * Since we cannot access the TextNode's HTML representation - * from the instance itself, we assign its data as textContent - * to a dummy buffer span, in order to retrieve the TextNode's - * HTML representation from the buffer's innerHTML. - */ - buffer.textContent = node.data; - var nodeHTML = buffer.innerHTML; - /** - * Apply function only on TextNodes - */ - if (node.nodeType != node.TEXT_NODE) { - continue; - } - var url = exports.findLinkMatch(node.data, lenient); - if (!url) { - continue; - } - var startsWithProtocol = new RegExp('^' + protocolClause), urlHasProtocol = url.match(startsWithProtocol), href = (urlHasProtocol) ? url : 'http://' + url, link = '' + url + '', newHTML = nodeHTML.replace(url, link); - line.innerHTML = line.innerHTML.replace(nodeHTML, newHTML); - } - /** - * This event gets emitted when conversion of all URL susbtrings - * to HTML anchor elements (links) has finished, for a specific - * line of the current Xterm instance. - * - * @event linkify:line - */ - terminal.emit('linkify:line', line); - }; + terminal.emit('linkify:line', line); + }; + + /** + * Finds a link within a block of text. + * + * @param {string} text - The text to search . + * @param {boolean} lenient - Whether to use the lenient search. + * @return {string} A URL. + */ + exports.findLinkMatch = function (text, lenient) { + var match = text.match(lenient ? lenientUrlRegex : strictUrlRegex); + if (!match || match.length === 0) { + return null; + } + return match[1]; + } + + /** + * Converts all valid URLs found in the terminal view into hyperlinks. + * + * @param {Xterm} terminal - The terminal that should get "linkified". + * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is + * false, the regex requires a protocol clause. Defaults to true. + * @param {string} target - Sets target="" attribute with value provided to links. + * Default doesn't set target attribute + * @emits linkify + * @emits linkify:line + */ + exports.linkify = function (terminal, lenient, target) { + var rows = terminal.rowContainer.children; + + lenient = (typeof lenient == "boolean") ? lenient : true; + for (var i=0; i 0) { - self.terminal.handler(diff); - } - } - }, 0); - }; - /** - * Positions the composition view on top of the cursor and the textarea just below it (so the - * IME helper dialog is positioned correctly). - * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is - * necessary as the IME events across browsers are not consistently triggered. - */ - CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) { - if (!this.isComposing) { - return; - } - var cursor = this.terminal.element.querySelector('.terminal-cursor'); - if (cursor) { - // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within - // the .xterm element. - var xtermRows = this.terminal.element.querySelector('.xterm-rows'); - var cursorTop = xtermRows.offsetTop + cursor.offsetTop; - this.compositionView.style.left = cursor.offsetLeft + 'px'; - this.compositionView.style.top = cursorTop + 'px'; - this.compositionView.style.height = cursor.offsetHeight + 'px'; - this.compositionView.style.lineHeight = cursor.offsetHeight + 'px'; - // Sync the textarea to the exact position of the composition view so the IME knows where the - // text is. - var compositionViewBounds = this.compositionView.getBoundingClientRect(); - this.textarea.style.left = cursor.offsetLeft + 'px'; - this.textarea.style.top = cursorTop + 'px'; - this.textarea.style.width = compositionViewBounds.width + 'px'; - this.textarea.style.height = compositionViewBounds.height + 'px'; - this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; - } - if (!dontRecurse) { - setTimeout(this.updateCompositionElements.bind(this, true), 0); - } - }; - ; - /** - * Clears the textarea's position so that the cursor does not blink on IE. - * @private - */ - CompositionHelper.prototype.clearTextareaPosition = function () { - this.textarea.style.left = ''; - this.textarea.style.top = ''; - }; - ; - return CompositionHelper; -}()); -exports.CompositionHelper = CompositionHelper; - -},{}],2:[function(require,module,exports){ -/** - * @license MIT - */ -"use strict"; -function EventEmitter() { - this._events = this._events || {}; -} -exports.EventEmitter = EventEmitter; -EventEmitter.prototype.addListener = function (type, listener) { - this._events[type] = this._events[type] || []; - this._events[type].push(listener); -}; -EventEmitter.prototype.on = EventEmitter.prototype.addListener; -EventEmitter.prototype.removeListener = function (type, listener) { - if (!this._events[type]) - return; - var obj = this._events[type], i = obj.length; - while (i--) { - if (obj[i] === listener || obj[i].listener === listener) { - obj.splice(i, 1); - return; - } - } -}; -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; -EventEmitter.prototype.removeAllListeners = function (type) { - if (this._events[type]) - delete this._events[type]; -}; -EventEmitter.prototype.once = function (type, listener) { - var self = this; - function on() { - var args = Array.prototype.slice.call(arguments); - this.removeListener(type, on); - return listener.apply(this, args); - } - on.listener = listener; - return this.on(type, on); -}; -EventEmitter.prototype.emit = function (type) { - if (!this._events[type]) - return; - var args = Array.prototype.slice.call(arguments, 1), obj = this._events[type], l = obj.length, i = 0; - for (; i < l; i++) { - obj[i].apply(this, args); - } -}; -EventEmitter.prototype.listeners = function (type) { - return this._events[type] = this._events[type] || []; -}; - -},{}],3:[function(require,module,exports){ -/** - * @license MIT - */ -"use strict"; -/** - * Represents the viewport of a terminal, the visible area within the larger buffer of output. - * Logic for the virtual scroll bar is included in this object. - */ -var Viewport = (function () { - /** - * Creates a new Viewport. - * @param terminal The terminal this viewport belongs to. - * @param viewportElement The DOM element acting as the viewport. - * @param scrollArea The DOM element acting as the scroll area. - * @param charMeasureElement A DOM element used to measure the character size of. the terminal. - */ - function Viewport(terminal, viewportElement, scrollArea, charMeasureElement) { - this.terminal = terminal; - this.viewportElement = viewportElement; - this.scrollArea = scrollArea; - this.charMeasureElement = charMeasureElement; - this.currentRowHeight = 0; - this.lastRecordedBufferLength = 0; - this.lastRecordedViewportHeight = 0; - this.terminal.on('scroll', this.syncScrollArea.bind(this)); - this.terminal.on('resize', this.syncScrollArea.bind(this)); - this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); - this.syncScrollArea(); - } - /** - * Refreshes row height, setting line-height, viewport height and scroll area height if - * necessary. - * @param charSize A character size measurement bounding rect object, if it doesn't exist it will - * be created. - */ - Viewport.prototype.refresh = function (charSize) { - var size = charSize || this.charMeasureElement.getBoundingClientRect(); - if (size.height > 0) { - var rowHeightChanged = size.height !== this.currentRowHeight; - if (rowHeightChanged) { - this.currentRowHeight = size.height; - this.viewportElement.style.lineHeight = size.height + 'px'; - this.terminal.rowContainer.style.lineHeight = size.height + 'px'; - } - var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows; - if (rowHeightChanged || viewportHeightChanged) { - this.lastRecordedViewportHeight = this.terminal.rows; - this.viewportElement.style.height = size.height * this.terminal.rows + 'px'; - } - this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px'; - } - }; - /** - * Updates dimensions and synchronizes the scroll area if necessary. - */ - Viewport.prototype.syncScrollArea = function () { - if (this.lastRecordedBufferLength !== this.terminal.lines.length) { - // If buffer height changed - this.lastRecordedBufferLength = this.terminal.lines.length; - this.refresh(); - } - else if (this.lastRecordedViewportHeight !== this.terminal.rows) { - // If viewport height changed - this.refresh(); - } - else { - // If size has changed, refresh viewport - var size = this.charMeasureElement.getBoundingClientRect(); - if (size.height !== this.currentRowHeight) { - this.refresh(size); - } - } - // Sync scrollTop - var scrollTop = this.terminal.ydisp * this.currentRowHeight; - if (this.viewportElement.scrollTop !== scrollTop) { - this.viewportElement.scrollTop = scrollTop; - } - }; - /** - * Handles scroll events on the viewport, calculating the new viewport and requesting the - * terminal to scroll to it. - * @param ev The scroll event. - */ - Viewport.prototype.onScroll = function (ev) { - var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); - var diff = newRow - this.terminal.ydisp; - this.terminal.scrollDisp(diff, true); - }; - /** - * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual - * scrolling to `onScroll`, this event needs to be attached manually by the consumer of - * `Viewport`. - * @param ev The mouse wheel event. - */ - Viewport.prototype.onWheel = function (ev) { - if (ev.deltaY === 0) { - // Do nothing if it's not a vertical scroll event - return; - } - // Fallback to WheelEvent.DOM_DELTA_PIXEL - var multiplier = 1; - if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { - multiplier = this.currentRowHeight; - } - else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { - multiplier = this.currentRowHeight * this.terminal.rows; - } - this.viewportElement.scrollTop += ev.deltaY * multiplier; - // Prevent the page from scrolling when the terminal scrolls - ev.preventDefault(); - }; - ; - return Viewport; -}()); -exports.Viewport = Viewport; - -},{}],4:[function(require,module,exports){ -/** - * Clipboard handler module: exports methods for handling all clipboard-related events in the - * terminal. - * @module xterm/handlers/Clipboard - * @license MIT - */ -"use strict"; -/** - * Prepares text copied from terminal selection, to be saved in the clipboard by: - * 1. stripping all trailing white spaces - * 2. converting all non-breaking spaces to regular spaces - * @param {string} text The copied text that needs processing for storing in clipboard - * @returns {string} - */ -function prepareTextForClipboard(text) { - var space = String.fromCharCode(32), nonBreakingSpace = String.fromCharCode(160), allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'), processedText = text.split('\n').map(function (line) { - // Strip all trailing white spaces and convert all non-breaking spaces - // to regular spaces. - var processedLine = line.replace(/\s+$/g, '').replace(allNonBreakingSpaces, space); - return processedLine; - }).join('\n'); - return processedText; -} -exports.prepareTextForClipboard = prepareTextForClipboard; -/** - * Binds copy functionality to the given terminal. - * @param {ClipboardEvent} ev The original copy event to be handled - */ -function copyHandler(ev, term) { - // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData` - // property that we use below for Internet Explorer. - var copiedText = window.getSelection().toString(), text = prepareTextForClipboard(copiedText); - if (term.browser.isMSIE) { - window.clipboardData.setData('Text', text); - } - else { - ev.clipboardData.setData('text/plain', text); - } - ev.preventDefault(); // Prevent or the original text will be copied. -} -exports.copyHandler = copyHandler; -/** - * Redirect the clipboard's data to the terminal's input handler. - * @param {ClipboardEvent} ev The original paste event to be handled - * @param {Terminal} term The terminal on which to apply the handled paste event - */ -function pasteHandler(ev, term) { - ev.stopPropagation(); - var text; - var dispatchPaste = function (text) { - term.handler(text); - term.textarea.value = ''; - return term.cancel(ev); - }; - if (term.browser.isMSIE) { - if (window.clipboardData) { - text = window.clipboardData.getData('Text'); - dispatchPaste(text); - } - } - else { - if (ev.clipboardData) { - text = ev.clipboardData.getData('text/plain'); - dispatchPaste(text); - } - } -} -exports.pasteHandler = pasteHandler; -/** - * Bind to right-click event and allow right-click copy and paste. - * - * **Logic** - * If text is selected and right-click happens on selected text, then - * do nothing to allow seamless copying. - * If no text is selected or right-click is outside of the selection - * area, then bring the terminal's input below the cursor, in order to - * trigger the event on the textarea and allow-right click paste, without - * caring about disappearing selection. - * @param {MouseEvent} ev The original right click event to be handled - * @param {Terminal} term The terminal on which to apply the handled paste event - */ -function rightClickHandler(ev, term) { - var s = document.getSelection(), selectedText = prepareTextForClipboard(s.toString()), clickIsOnSelection = false, x = ev.clientX, y = ev.clientY; - if (s.rangeCount) { - var r = s.getRangeAt(0), cr = r.getClientRects(); - for (var i = 0; i < cr.length; i++) { - var rect = cr[i]; - clickIsOnSelection = ((x > rect.left) && (x < rect.right) && - (y > rect.top) && (y < rect.bottom)); - if (clickIsOnSelection) { - break; - } - } - // If we clicked on selection and selection is not a single space, - // then mark the right click as copy-only. We check for the single - // space selection, as this can happen when clicking on an   - // and there is not much pointing in copying a single space. - if (selectedText.match(/^\s$/) || !selectedText.length) { - clickIsOnSelection = false; - } - } - // Bring textarea at the cursor position - if (!clickIsOnSelection) { - term.textarea.style.position = 'fixed'; - term.textarea.style.width = '20px'; - term.textarea.style.height = '20px'; - term.textarea.style.left = (x - 10) + 'px'; - term.textarea.style.top = (y - 10) + 'px'; - term.textarea.style.zIndex = '1000'; - term.textarea.focus(); - // Reset the terminal textarea's styling - setTimeout(function () { - term.textarea.style.position = null; - term.textarea.style.width = null; - term.textarea.style.height = null; - term.textarea.style.left = null; - term.textarea.style.top = null; - term.textarea.style.zIndex = null; - }, 4); - } -} -exports.rightClickHandler = rightClickHandler; - -},{}],5:[function(require,module,exports){ -/** - * Attributes and methods to help with identifying the current browser and platform. - * @module xterm/utils/Browser - * @license MIT - */ -"use strict"; -var Generic_js_1 = require('./Generic.js'); -var isNode = (typeof navigator == 'undefined') ? true : false; -var userAgent = (isNode) ? 'node' : navigator.userAgent; -var platform = (isNode) ? 'node' : navigator.platform; -exports.isFirefox = !!~userAgent.indexOf('Firefox'); -exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident'); -// Find the users platform. We use this to interpret the meta key -// and ISO third level shifts. -// http://stackoverflow.com/q/19877924/577598 -exports.isMac = Generic_js_1.contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform); -exports.isIpad = platform === 'iPad'; -exports.isIphone = platform === 'iPhone'; -exports.isMSWindows = Generic_js_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); - -},{"./Generic.js":6}],6:[function(require,module,exports){ -/** - * Generic utilities module with methods that can be helpful at different parts of the code base. - * @module xterm/utils/Generic - * @license MIT - */ -"use strict"; -/** - * Return if the given array contains the given element - * @param {Array} array The array to search for the given element. - * @param {Object} el The element to look for into the array - */ -exports.contains = function (arr, el) { - return arr.indexOf(el) >= 0; -}; - -},{}],7:[function(require,module,exports){ -/** - * xterm.js: xterm, in the browser - * Originally forked from (with the author's permission): - * Fabrice Bellard's javascript vt100 for jslinux: - * http://bellard.org/jslinux/ - * Copyright (c) 2011 Fabrice Bellard - * The original design remains. The terminal itself - * has been extended to include xterm CSI codes, among - * other features. - * @license MIT - */ -"use strict"; -var CompositionHelper_js_1 = require('./CompositionHelper.js'); -var EventEmitter_js_1 = require('./EventEmitter.js'); -var Viewport_js_1 = require('./Viewport.js'); -var Clipboard_js_1 = require('./handlers/Clipboard.js'); -var Browser = require('./utils/Browser'); -/** - * Terminal Emulation References: - * http://vt100.net/ - * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt - * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html - * http://invisible-island.net/vttest/ - * http://www.inwap.com/pdp10/ansicode.txt - * http://linux.die.net/man/4/console_codes - * http://linux.die.net/man/7/urxvt - */ -// Let it work inside Node.js for automated testing purposes. -var document = (typeof window != 'undefined') ? window.document : null; -/** - * States - */ -var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6; -/** - * Terminal - */ -/** - * Creates a new `Terminal` object. - * - * @param {object} options An object containing a set of options, the available options are: - * - `cursorBlink` (boolean): Whether the terminal cursor blinks - * - `cols` (number): The number of columns of the terminal (horizontal size) - * - `rows` (number): The number of rows of the terminal (vertical size) - * - * @public - * @class Xterm Xterm - * @alias module:xterm/src/xterm - */ -function Terminal(options) { - var self = this; - if (!(this instanceof Terminal)) { - return new Terminal(arguments[0], arguments[1], arguments[2]); - } - self.browser = Browser; - self.cancel = Terminal.cancel; - EventEmitter_js_1.EventEmitter.call(this); - if (typeof options === 'number') { - options = { - cols: arguments[0], - rows: arguments[1], - handler: arguments[2] - }; - } - options = options || {}; - Object.keys(Terminal.defaults).forEach(function (key) { - if (options[key] == null) { - options[key] = Terminal.options[key]; - if (Terminal[key] !== Terminal.defaults[key]) { - options[key] = Terminal[key]; - } - } - self[key] = options[key]; - }); - if (options.colors.length === 8) { - options.colors = options.colors.concat(Terminal._colors.slice(8)); - } - else if (options.colors.length === 16) { - options.colors = options.colors.concat(Terminal._colors.slice(16)); - } - else if (options.colors.length === 10) { - options.colors = options.colors.slice(0, -2).concat(Terminal._colors.slice(8, -2), options.colors.slice(-2)); - } - else if (options.colors.length === 18) { - options.colors = options.colors.concat(Terminal._colors.slice(16, -2), options.colors.slice(-2)); - } - this.colors = options.colors; - this.options = options; - // this.context = options.context || window; - // this.document = options.document || document; - this.parent = options.body || options.parent || (document ? document.getElementsByTagName('body')[0] : null); - this.cols = options.cols || options.geometry[0]; - this.rows = options.rows || options.geometry[1]; - this.geometry = [this.cols, this.rows]; - if (options.handler) { - this.on('data', options.handler); - } - /** - * The scroll position of the y cursor, ie. ybase + y = the y position within the entire - * buffer - */ - this.ybase = 0; - /** - * The scroll position of the viewport - */ - this.ydisp = 0; - /** - * The cursor's x position after ybase - */ - this.x = 0; - /** - * The cursor's y position after ybase - */ - this.y = 0; - /** - * Used to debounce the refresh function - */ - this.isRefreshing = false; - /** - * Whether there is a full terminal refresh queued - */ - this.cursorState = 0; - this.cursorHidden = false; - this.convertEol; - this.state = 0; - this.queue = ''; - this.scrollTop = 0; - this.scrollBottom = this.rows - 1; - this.customKeydownHandler = null; - // modes - this.applicationKeypad = false; - this.applicationCursor = false; - this.originMode = false; - this.insertMode = false; - this.wraparoundMode = true; // defaults: xterm - true, vt100 - false - this.normal = null; - // charset - this.charset = null; - this.gcharset = null; - this.glevel = 0; - this.charsets = [null]; - // mouse properties - this.decLocator; - this.x10Mouse; - this.vt200Mouse; - this.vt300Mouse; - this.normalMouse; - this.mouseEvents; - this.sendFocus; - this.utfMouse; - this.sgrMouse; - this.urxvtMouse; - // misc - this.element; - this.children; - this.refreshStart; - this.refreshEnd; - this.savedX; - this.savedY; - this.savedCols; - // stream - this.readable = true; - this.writable = true; - this.defAttr = (0 << 18) | (257 << 9) | (256 << 0); - this.curAttr = this.defAttr; - this.params = []; - this.currentParam = 0; - this.prefix = ''; - this.postfix = ''; - // leftover surrogate high from previous write invocation - this.surrogate_high = ''; - /** - * An array of all lines in the entire buffer, including the prompt. The lines are array of - * characters which are 2-length arrays where [0] is an attribute and [1] is the character. - */ - this.lines = []; - var i = this.rows; - while (i--) { - this.lines.push(this.blankLine()); - } - this.tabs; - this.setupStops(); - // Store if user went browsing history in scrollback - this.userScrolling = false; -} -inherits(Terminal, EventEmitter_js_1.EventEmitter); -/** - * back_color_erase feature for xterm. - */ -Terminal.prototype.eraseAttr = function () { - // if (this.is('screen')) return this.defAttr; - return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff); -}; -/** - * Colors - */ -// Colors 0-15 -Terminal.tangoColors = [ - // dark: - '#2e3436', - '#cc0000', - '#4e9a06', - '#c4a000', - '#3465a4', - '#75507b', - '#06989a', - '#d3d7cf', - // bright: - '#555753', - '#ef2929', - '#8ae234', - '#fce94f', - '#729fcf', - '#ad7fa8', - '#34e2e2', - '#eeeeec' -]; -// Colors 0-15 + 16-255 -// Much thanks to TooTallNate for writing this. -Terminal.colors = (function () { - var colors = Terminal.tangoColors.slice(), r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff], i; - // 16-231 - i = 0; - for (; i < 216; i++) { - out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]); - } - // 232-255 (grey) - i = 0; - for (; i < 24; i++) { - r = 8 + i * 10; - out(r, r, r); - } - function out(r, g, b) { - colors.push('#' + hex(r) + hex(g) + hex(b)); - } - function hex(c) { - c = c.toString(16); - return c.length < 2 ? '0' + c : c; - } - return colors; -})(); -Terminal._colors = Terminal.colors.slice(); -Terminal.vcolors = (function () { - var out = [], colors = Terminal.colors, i = 0, color; - for (; i < 256; i++) { - color = parseInt(colors[i].substring(1), 16); - out.push([ - (color >> 16) & 0xff, - (color >> 8) & 0xff, - color & 0xff - ]); - } - return out; -})(); -/** - * Options - */ -Terminal.defaults = { - colors: Terminal.colors, - theme: 'default', - convertEol: false, - termName: 'xterm', - geometry: [80, 24], - cursorBlink: false, - visualBell: false, - popOnBell: false, - scrollback: 1000, - screenKeys: false, - debug: false, - cancelEvents: false -}; -Terminal.options = {}; -Terminal.focus = null; -each(keys(Terminal.defaults), function (key) { - Terminal[key] = Terminal.defaults[key]; - Terminal.options[key] = Terminal.defaults[key]; -}); -/** - * Focus the terminal. Delegates focus handling to the terminal's DOM element. - */ -Terminal.prototype.focus = function () { - return this.textarea.focus(); -}; -/** - * Retrieves an option's value from the terminal. - * @param {string} key The option key. - */ -Terminal.prototype.getOption = function (key, value) { - if (!(key in Terminal.defaults)) { - throw new Error('No option with key "' + key + '"'); - } - if (typeof this.options[key] !== 'undefined') { - return this.options[key]; - } - return this[key]; -}; -/** - * Sets an option on the terminal. - * @param {string} key The option key. - * @param {string} value The option value. - */ -Terminal.prototype.setOption = function (key, value) { - if (!(key in Terminal.defaults)) { - throw new Error('No option with key "' + key + '"'); - } - this[key] = value; - this.options[key] = value; -}; -/** - * Binds the desired focus behavior on a given terminal object. - * - * @static - */ -Terminal.bindFocus = function (term) { - on(term.textarea, 'focus', function (ev) { - if (term.sendFocus) { - term.send('\x1b[I'); - } - term.element.classList.add('focus'); - term.showCursor(); - Terminal.focus = term; - term.emit('focus', { terminal: term }); - }); -}; -/** - * Blur the terminal. Delegates blur handling to the terminal's DOM element. - */ -Terminal.prototype.blur = function () { - return this.textarea.blur(); -}; -/** - * Binds the desired blur behavior on a given terminal object. - * - * @static - */ -Terminal.bindBlur = function (term) { - on(term.textarea, 'blur', function (ev) { - term.refresh(term.y, term.y); - if (term.sendFocus) { - term.send('\x1b[O'); - } - term.element.classList.remove('focus'); - Terminal.focus = null; - term.emit('blur', { terminal: term }); - }); -}; -/** - * Initialize default behavior - */ -Terminal.prototype.initGlobal = function () { - var term = this; - Terminal.bindKeys(this); - Terminal.bindFocus(this); - Terminal.bindBlur(this); - // Bind clipboard functionality - on(this.element, 'copy', function (ev) { - Clipboard_js_1.copyHandler.call(this, ev, term); - }); - on(this.textarea, 'paste', function (ev) { - Clipboard_js_1.pasteHandler.call(this, ev, term); - }); - on(this.element, 'paste', function (ev) { - Clipboard_js_1.pasteHandler.call(this, ev, term); - }); - function rightClickHandlerWrapper(ev) { - Clipboard_js_1.rightClickHandler.call(this, ev, term); - } - if (term.browser.isFirefox) { - on(this.element, 'mousedown', function (ev) { - if (ev.button == 2) { - rightClickHandlerWrapper(ev); - } - }); - } - else { - on(this.element, 'contextmenu', rightClickHandlerWrapper); - } -}; -/** - * Apply key handling to the terminal - */ -Terminal.bindKeys = function (term) { - on(term.element, 'keydown', function (ev) { - if (document.activeElement != this) { - return; - } - term.keyDown(ev); - }, true); - on(term.element, 'keypress', function (ev) { - if (document.activeElement != this) { - return; - } - term.keyPress(ev); - }, true); - on(term.element, 'keyup', term.focus.bind(term)); - on(term.textarea, 'keydown', function (ev) { - term.keyDown(ev); - }, true); - on(term.textarea, 'keypress', function (ev) { - term.keyPress(ev); - // Truncate the textarea's value, since it is not needed - this.value = ''; - }, true); - on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper)); - on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper)); - on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper)); - term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper)); -}; -/** - * Insert the given row to the terminal or produce a new one - * if no row argument is passed. Return the inserted row. - * @param {HTMLElement} row (optional) The row to append to the terminal. - */ -Terminal.prototype.insertRow = function (row) { - if (typeof row != 'object') { - row = document.createElement('div'); - } - this.rowContainer.appendChild(row); - this.children.push(row); - return row; -}; -/** - * Opens the terminal within an element. - * - * @param {HTMLElement} parent The element to create the terminal within. - */ -Terminal.prototype.open = function (parent) { - var self = this, i = 0, div; - this.parent = parent || this.parent; - if (!this.parent) { - throw new Error('Terminal requires a parent element.'); - } - // Grab global elements - this.context = this.parent.ownerDocument.defaultView; - this.document = this.parent.ownerDocument; - this.body = this.document.getElementsByTagName('body')[0]; - //Create main element container - this.element = this.document.createElement('div'); - this.element.classList.add('terminal'); - this.element.classList.add('xterm'); - this.element.classList.add('xterm-theme-' + this.theme); - this.element.style.height; - this.element.setAttribute('tabindex', 0); - this.viewportElement = document.createElement('div'); - this.viewportElement.classList.add('xterm-viewport'); - this.element.appendChild(this.viewportElement); - this.viewportScrollArea = document.createElement('div'); - this.viewportScrollArea.classList.add('xterm-scroll-area'); - this.viewportElement.appendChild(this.viewportScrollArea); - // Create the container that will hold the lines of the terminal and then - // produce the lines the lines. - this.rowContainer = document.createElement('div'); - this.rowContainer.classList.add('xterm-rows'); - this.element.appendChild(this.rowContainer); - this.children = []; - // Create the container that will hold helpers like the textarea for - // capturing DOM Events. Then produce the helpers. - this.helperContainer = document.createElement('div'); - this.helperContainer.classList.add('xterm-helpers'); - // TODO: This should probably be inserted once it's filled to prevent an additional layout - this.element.appendChild(this.helperContainer); - this.textarea = document.createElement('textarea'); - this.textarea.classList.add('xterm-helper-textarea'); - this.textarea.setAttribute('autocorrect', 'off'); - this.textarea.setAttribute('autocapitalize', 'off'); - this.textarea.setAttribute('spellcheck', 'false'); - this.textarea.tabIndex = 0; - this.textarea.addEventListener('focus', function () { - self.emit('focus', { terminal: self }); - }); - this.textarea.addEventListener('blur', function () { - self.emit('blur', { terminal: self }); - }); - this.helperContainer.appendChild(this.textarea); - this.compositionView = document.createElement('div'); - this.compositionView.classList.add('composition-view'); - this.compositionHelper = new CompositionHelper_js_1.CompositionHelper(this.textarea, this.compositionView, this); - this.helperContainer.appendChild(this.compositionView); - this.charMeasureElement = document.createElement('div'); - this.charMeasureElement.classList.add('xterm-char-measure-element'); - this.charMeasureElement.innerHTML = 'W'; - this.helperContainer.appendChild(this.charMeasureElement); - for (; i < this.rows; i++) { - this.insertRow(); - } - this.parent.appendChild(this.element); - this.viewport = new Viewport_js_1.Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasureElement); - // Draw the screen. - this.refresh(0, this.rows - 1); - // Initialize global actions that - // need to be taken on the document. - this.initGlobal(); - // Ensure there is a Terminal.focus. - this.focus(); - on(this.element, 'click', function () { - var selection = document.getSelection(), collapsed = selection.isCollapsed, isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range'; - if (!isRange) { - self.focus(); - } - }); - // Listen for mouse events and translate - // them into terminal mouse protocols. - this.bindMouse(); - // Figure out whether boldness affects - // the character width of monospace fonts. - if (Terminal.brokenBold == null) { - Terminal.brokenBold = isBoldBroken(this.document); - } - /** - * This event is emitted when terminal has completed opening. - * - * @event open - */ - this.emit('open'); -}; -/** - * Attempts to load an add-on using CommonJS or RequireJS (whichever is available). - * @param {string} addon The name of the addon to load - * @static - */ -Terminal.loadAddon = function (addon, callback) { - if (typeof exports === 'object' && typeof module === 'object') { - // CommonJS - return require('./addons/' + addon + '/' + addon); - } - else if (typeof define == 'function') { - // RequireJS - return require(['./addons/' + addon + '/' + addon], callback); - } - else { - console.error('Cannot load a module without a CommonJS or RequireJS environment.'); - return false; - } -}; -/** - * XTerm mouse events - * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking - * To better understand these - * the xterm code is very helpful: - * Relevant files: - * button.c, charproc.c, misc.c - * Relevant functions in xterm/button.c: - * BtnCode, EmitButtonCode, EditorButton, SendMousePosition - */ -Terminal.prototype.bindMouse = function () { - var el = this.element, self = this, pressed = 32; - // mouseup, mousedown, wheel - // left click: ^[[M 3<^[[M#3< - // wheel up: ^[[M`3> - function sendButton(ev) { - var button, pos; - // get the xterm-style button - button = getButton(ev); - // get mouse coordinates - pos = getCoords(ev); - if (!pos) - return; - sendEvent(button, pos); - switch (ev.overrideType || ev.type) { - case 'mousedown': - pressed = button; - break; - case 'mouseup': - // keep it at the left - // button, just in case. - pressed = 32; - break; - case 'wheel': - // nothing. don't - // interfere with - // `pressed`. - break; - } - } - // motion example of a left click: - // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7< - function sendMove(ev) { - var button = pressed, pos; - pos = getCoords(ev); - if (!pos) - return; - // buttons marked as motions - // are incremented by 32 - button += 32; - sendEvent(button, pos); - } - // encode button and - // position to characters - function encode(data, ch) { - if (!self.utfMouse) { - if (ch === 255) - return data.push(0); - if (ch > 127) - ch = 127; - data.push(ch); - } - else { - if (ch === 2047) - return data.push(0); - if (ch < 127) { - data.push(ch); - } - else { - if (ch > 2047) - ch = 2047; - data.push(0xC0 | (ch >> 6)); - data.push(0x80 | (ch & 0x3F)); - } - } - } - // send a mouse event: - // regular/utf8: ^[[M Cb Cx Cy - // urxvt: ^[[ Cb ; Cx ; Cy M - // sgr: ^[[ Cb ; Cx ; Cy M/m - // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r - // locator: CSI P e ; P b ; P r ; P c ; P p & w - function sendEvent(button, pos) { - // self.emit('mouse', { - // x: pos.x - 32, - // y: pos.x - 32, - // button: button - // }); - if (self.vt300Mouse) { - // NOTE: Unstable. - // http://www.vt100.net/docs/vt3xx-gp/chapter15.html - button &= 3; - pos.x -= 32; - pos.y -= 32; - var data = '\x1b[24'; - if (button === 0) - data += '1'; - else if (button === 1) - data += '3'; - else if (button === 2) - data += '5'; - else if (button === 3) - return; - else - data += '0'; - data += '~[' + pos.x + ',' + pos.y + ']\r'; - self.send(data); - return; - } - if (self.decLocator) { - // NOTE: Unstable. - button &= 3; - pos.x -= 32; - pos.y -= 32; - if (button === 0) - button = 2; - else if (button === 1) - button = 4; - else if (button === 2) - button = 6; - else if (button === 3) - button = 3; - self.send('\x1b[' - + button - + ';' - + (button === 3 ? 4 : 0) - + ';' - + pos.y - + ';' - + pos.x - + ';' - + (pos.page || 0) - + '&w'); - return; - } - if (self.urxvtMouse) { - pos.x -= 32; - pos.y -= 32; - pos.x++; - pos.y++; - self.send('\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M'); - return; - } - if (self.sgrMouse) { - pos.x -= 32; - pos.y -= 32; - self.send('\x1b[<' - + (((button & 3) === 3 ? button & ~3 : button) - 32) - + ';' - + pos.x - + ';' - + pos.y - + ((button & 3) === 3 ? 'm' : 'M')); - return; - } - var data = []; - encode(data, button); - encode(data, pos.x); - encode(data, pos.y); - self.send('\x1b[M' + String.fromCharCode.apply(String, data)); - } - function getButton(ev) { - var button, shift, meta, ctrl, mod; - // two low bits: - // 0 = left - // 1 = middle - // 2 = right - // 3 = release - // wheel up/down: - // 1, and 2 - with 64 added - switch (ev.overrideType || ev.type) { - case 'mousedown': - button = ev.button != null - ? +ev.button - : ev.which != null - ? ev.which - 1 - : null; - if (self.browser.isMSIE) { - button = button === 1 ? 0 : button === 4 ? 1 : button; - } - break; - case 'mouseup': - button = 3; - break; - case 'DOMMouseScroll': - button = ev.detail < 0 - ? 64 - : 65; - break; - case 'wheel': - button = ev.wheelDeltaY > 0 - ? 64 - : 65; - break; - } - // next three bits are the modifiers: - // 4 = shift, 8 = meta, 16 = control - shift = ev.shiftKey ? 4 : 0; - meta = ev.metaKey ? 8 : 0; - ctrl = ev.ctrlKey ? 16 : 0; - mod = shift | meta | ctrl; - // no mods - if (self.vt200Mouse) { - // ctrl only - mod &= ctrl; - } - else if (!self.normalMouse) { - mod = 0; - } - // increment to SP - button = (32 + (mod << 2)) + button; - return button; - } - // mouse coordinates measured in cols/rows - function getCoords(ev) { - var x, y, w, h, el; - // ignore browsers without pageX for now - if (ev.pageX == null) - return; - x = ev.pageX; - y = ev.pageY; - el = self.element; - // should probably check offsetParent - // but this is more portable - while (el && el !== self.document.documentElement) { - x -= el.offsetLeft; - y -= el.offsetTop; - el = 'offsetParent' in el - ? el.offsetParent - : el.parentNode; - } - // convert to cols/rows - w = self.element.clientWidth; - h = self.element.clientHeight; - x = Math.ceil((x / w) * self.cols); - y = Math.ceil((y / h) * self.rows); - // be sure to avoid sending - // bad positions to the program - if (x < 0) - x = 0; - if (x > self.cols) - x = self.cols; - if (y < 0) - y = 0; - if (y > self.rows) - y = self.rows; - // xterm sends raw bytes and - // starts at 32 (SP) for each. - x += 32; - y += 32; - return { - x: x, - y: y, - type: 'wheel' - }; - } - on(el, 'mousedown', function (ev) { - if (!self.mouseEvents) - return; - // send the button - sendButton(ev); - // ensure focus - self.focus(); - // fix for odd bug - //if (self.vt200Mouse && !self.normalMouse) { - if (self.vt200Mouse) { - ev.overrideType = 'mouseup'; - sendButton(ev); - return self.cancel(ev); - } - // bind events - if (self.normalMouse) - on(self.document, 'mousemove', sendMove); - // x10 compatibility mode can't send button releases - if (!self.x10Mouse) { - on(self.document, 'mouseup', function up(ev) { - sendButton(ev); - if (self.normalMouse) - off(self.document, 'mousemove', sendMove); - off(self.document, 'mouseup', up); - return self.cancel(ev); - }); - } - return self.cancel(ev); - }); - //if (self.normalMouse) { - // on(self.document, 'mousemove', sendMove); - //} - on(el, 'wheel', function (ev) { - if (!self.mouseEvents) - return; - if (self.x10Mouse - || self.vt300Mouse - || self.decLocator) - return; - sendButton(ev); - return self.cancel(ev); - }); - // allow wheel scrolling in - // the shell for example - on(el, 'wheel', function (ev) { - if (self.mouseEvents) - return; - self.viewport.onWheel(ev); - return self.cancel(ev); - }); -}; -/** - * Destroys the terminal. - */ -Terminal.prototype.destroy = function () { - this.readable = false; - this.writable = false; - this._events = {}; - this.handler = function () { }; - this.write = function () { }; - if (this.element.parentNode) { - this.element.parentNode.removeChild(this.element); - } - //this.emit('close'); -}; -/** - * Flags used to render terminal text properly - */ -Terminal.flags = { - BOLD: 1, - UNDERLINE: 2, - BLINK: 4, - INVERSE: 8, - INVISIBLE: 16 -}; -/** - * Refreshes (re-renders) terminal content within two rows (inclusive) - * - * Rendering Engine: - * - * In the screen buffer, each character is stored as a an array with a character - * and a 32-bit integer: - * - First value: a utf-16 character. - * - Second value: - * - Next 9 bits: background color (0-511). - * - Next 9 bits: foreground color (0-511). - * - Next 14 bits: a mask for misc. flags: - * - 1=bold - * - 2=underline - * - 4=blink - * - 8=inverse - * - 16=invisible - * - * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) - * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) - * @param {boolean} queue Whether the refresh should ran right now or be queued - */ -Terminal.prototype.refresh = function (start, end, queue) { - var self = this; - // queue defaults to true - queue = (typeof queue == 'undefined') ? true : queue; - /** - * The refresh queue allows refresh to execute only approximately 30 times a second. For - * commands that pass a significant amount of output to the write function, this prevents the - * terminal from maxing out the CPU and making the UI unresponsive. While commands can still - * run beyond what they do on the terminal, it is far better with a debounce in place as - * every single terminal manipulation does not need to be constructed in the DOM. - * - * A side-effect of this is that it makes ^C to interrupt a process seem more responsive. - */ - if (queue) { - // If refresh should be queued, order the refresh and return. - if (this._refreshIsQueued) { - // If a refresh has already been queued, just order a full refresh next - this._fullRefreshNext = true; - } - else { - setTimeout(function () { - self.refresh(start, end, false); - }, 34); - this._refreshIsQueued = true; - } - return; - } - // If refresh should be run right now (not be queued), release the lock - this._refreshIsQueued = false; - // If multiple refreshes were requested, make a full refresh. - if (this._fullRefreshNext) { - start = 0; - end = this.rows - 1; - this._fullRefreshNext = false; // reset lock - } - var x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement; - // If this is a big refresh, remove the terminal rows from the DOM for faster calculations - if (end - start >= this.rows / 2) { - parent = this.element.parentNode; - if (parent) { - this.element.removeChild(this.rowContainer); - } - } - width = this.cols; - y = start; - if (end >= this.rows.length) { - this.log('`end` is too large. Most likely a bad CSR.'); - end = this.rows.length - 1; - } - for (; y <= end; y++) { - row = y + this.ydisp; - line = this.lines[row]; - out = ''; - if (this.y === y - (this.ybase - this.ydisp) - && this.cursorState - && !this.cursorHidden) { - x = this.x; - } - else { - x = -1; - } - attr = this.defAttr; - i = 0; - for (; i < width; i++) { - data = line[i][0]; - ch = line[i][1]; - ch_width = line[i][2]; - if (!ch_width) - continue; - if (i === x) - data = -1; - if (data !== attr) { - if (attr !== this.defAttr) { - out += ''; - } - if (data !== this.defAttr) { - if (data === -1) { - out += ''; - } - else { - var classNames = []; - bg = data & 0x1ff; - fg = (data >> 9) & 0x1ff; - flags = data >> 18; - if (flags & Terminal.flags.BOLD) { - if (!Terminal.brokenBold) { - classNames.push('xterm-bold'); - } - // See: XTerm*boldColors - if (fg < 8) - fg += 8; - } - if (flags & Terminal.flags.UNDERLINE) { - classNames.push('xterm-underline'); - } - if (flags & Terminal.flags.BLINK) { - classNames.push('xterm-blink'); - } - // If inverse flag is on, then swap the foreground and background variables. - if (flags & Terminal.flags.INVERSE) { - /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */ - bg = [fg, fg = bg][0]; - // Should inverse just be before the - // above boldColors effect instead? - if ((flags & 1) && fg < 8) - fg += 8; - } - if (flags & Terminal.flags.INVISIBLE) { - classNames.push('xterm-hidden'); - } - /** - * Weird situation: Invert flag used black foreground and white background results - * in invalid background color, positioned at the 256 index of the 256 terminal - * color map. Pin the colors manually in such a case. - * - * Source: https://github.com/sourcelair/xterm.js/issues/57 - */ - if (flags & Terminal.flags.INVERSE) { - if (bg == 257) { - bg = 15; - } - if (fg == 256) { - fg = 0; - } - } - if (bg < 256) { - classNames.push('xterm-bg-color-' + bg); - } - if (fg < 256) { - classNames.push('xterm-color-' + fg); - } - out += '': - out += '>'; - break; - default: - if (ch <= ' ') { - out += ' '; - } - else { - out += ch; - } - break; - } - attr = data; - } - if (attr !== this.defAttr) { - out += ''; - } - this.children[y].innerHTML = out; - } - if (parent) { - this.element.appendChild(this.rowContainer); - } - this.emit('refresh', { element: this.element, start: start, end: end }); -}; -/** - * Display the cursor element - */ -Terminal.prototype.showCursor = function () { - if (!this.cursorState) { - this.cursorState = 1; - this.refresh(this.y, this.y); - } -}; -/** - * Scroll the terminal - */ -Terminal.prototype.scroll = function () { - var row; - if (++this.ybase === this.scrollback) { - this.ybase = this.ybase / 2 | 0; - this.lines = this.lines.slice(-(this.ybase + this.rows) + 1); - } - if (!this.userScrolling) { - this.ydisp = this.ybase; - } - // last line - row = this.ybase + this.rows - 1; - // subtract the bottom scroll region - row -= this.rows - 1 - this.scrollBottom; - if (row === this.lines.length) { - // potential optimization: - // pushing is faster than splicing - // when they amount to the same - // behavior. - this.lines.push(this.blankLine()); - } - else { - // add our new line - this.lines.splice(row, 0, this.blankLine()); - } - if (this.scrollTop !== 0) { - if (this.ybase !== 0) { - this.ybase--; - if (!this.userScrolling) { - this.ydisp = this.ybase; - } - } - this.lines.splice(this.ybase + this.scrollTop, 1); - } - // this.maxRange(); - this.updateRange(this.scrollTop); - this.updateRange(this.scrollBottom); - /** - * This event is emitted whenever the terminal is scrolled. - * The one parameter passed is the new y display position. - * - * @event scroll - */ - this.emit('scroll', this.ydisp); -}; -/** - * Scroll the display of the terminal - * @param {number} disp The number of lines to scroll down (negatives scroll up). - * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used - * to avoid unwanted events being handled by the veiwport when the event was triggered from the - * viewport originally. - */ -Terminal.prototype.scrollDisp = function (disp, suppressScrollEvent) { - if (disp < 0) { - this.userScrolling = true; - } - else if (disp + this.ydisp >= this.ybase) { - this.userScrolling = false; - } - this.ydisp += disp; - if (this.ydisp > this.ybase) { - this.ydisp = this.ybase; - } - else if (this.ydisp < 0) { - this.ydisp = 0; - } - if (!suppressScrollEvent) { - this.emit('scroll', this.ydisp); - } - this.refresh(0, this.rows - 1); -}; -/** - * Scroll the display of the terminal by a number of pages. - * @param {number} pageCount The number of pages to scroll (negative scrolls up). - */ -Terminal.prototype.scrollPages = function (pageCount) { - this.scrollDisp(pageCount * (this.rows - 1)); -}; -/** - * Scrolls the display of the terminal to the top. - */ -Terminal.prototype.scrollToTop = function () { - this.scrollDisp(-this.ydisp); -}; -/** - * Scrolls the display of the terminal to the bottom. - */ -Terminal.prototype.scrollToBottom = function () { - this.scrollDisp(this.ybase - this.ydisp); -}; -/** - * Writes text to the terminal. - * @param {string} text The text to write to the terminal. - */ -Terminal.prototype.write = function (data) { - var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; - this.refreshStart = this.y; - this.refreshEnd = this.y; - // apply leftover surrogate high from last write - if (this.surrogate_high) { - data = this.surrogate_high + data; - this.surrogate_high = ''; - } - for (; i < l; i++) { - ch = data[i]; - // FIXME: higher chars than 0xa0 are not allowed in escape sequences - // --> maybe move to default - code = data.charCodeAt(i); - if (0xD800 <= code && code <= 0xDBFF) { - // we got a surrogate high - // get surrogate low (next 2 bytes) - low = data.charCodeAt(i + 1); - if (isNaN(low)) { - // end of data stream, save surrogate high - this.surrogate_high = ch; - continue; - } - code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; - ch += data.charAt(i + 1); - } - // surrogate low - already handled above - if (0xDC00 <= code && code <= 0xDFFF) - continue; - switch (this.state) { - case normal: - switch (ch) { - case '\x07': - this.bell(); - break; - // '\n', '\v', '\f' - case '\n': - case '\x0b': - case '\x0c': - if (this.convertEol) { - this.x = 0; - } - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); - } - break; - // '\r' - case '\r': - this.x = 0; - break; - // '\b' - case '\x08': - if (this.x > 0) { - this.x--; - } - break; - // '\t' - case '\t': - this.x = this.nextStop(); - break; - // shift out - case '\x0e': - this.setgLevel(1); - break; - // shift in - case '\x0f': - this.setgLevel(0); - break; - // '\e' - case '\x1b': - this.state = escaped; - break; - default: - // ' ' - // calculate print space - // expensive call, therefore we save width in line buffer - ch_width = wcwidth(code); - if (ch >= ' ') { - if (this.charset && this.charset[ch]) { - ch = this.charset[ch]; - } - row = this.y + this.ybase; - // insert combining char in last cell - // FIXME: needs handling after cursor jumps - if (!ch_width && this.x) { - // dont overflow left - if (this.lines[row][this.x - 1]) { - if (!this.lines[row][this.x - 1][2]) { - // found empty cell after fullwidth, need to go 2 cells back - if (this.lines[row][this.x - 2]) - this.lines[row][this.x - 2][1] += ch; - } - else { - this.lines[row][this.x - 1][1] += ch; - } - this.updateRange(this.y); - } - break; - } - // goto next line if ch would overflow - // TODO: needs a global min terminal width of 2 - if (this.x + ch_width - 1 >= this.cols) { - // autowrap - DECAWM - if (this.wraparoundMode) { - this.x = 0; - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); - } - } - else { - this.x = this.cols - 1; - if (ch_width === 2) - continue; - } - } - row = this.y + this.ybase; - // insert mode: move characters to right - if (this.insertMode) { - // do this twice for a fullwidth char - for (var moves = 0; moves < ch_width; ++moves) { - // remove last cell, if it's width is 0 - // we have to adjust the second last cell as well - var removed = this.lines[this.y + this.ybase].pop(); - if (removed[2] === 0 - && this.lines[row][this.cols - 2] - && this.lines[row][this.cols - 2][2] === 2) - this.lines[row][this.cols - 2] = [this.curAttr, ' ', 1]; - // insert empty cell at cursor - this.lines[row].splice(this.x, 0, [this.curAttr, ' ', 1]); - } - } - this.lines[row][this.x] = [this.curAttr, ch, ch_width]; - this.x++; - this.updateRange(this.y); - // fullwidth char - set next cell width to zero and advance cursor - if (ch_width === 2) { - this.lines[row][this.x] = [this.curAttr, '', 0]; - this.x++; - } - } - break; - } - break; - case escaped: - switch (ch) { - // ESC [ Control Sequence Introducer ( CSI is 0x9b). - case '[': - this.params = []; - this.currentParam = 0; - this.state = csi; - break; - // ESC ] Operating System Command ( OSC is 0x9d). - case ']': - this.params = []; - this.currentParam = 0; - this.state = osc; - break; - // ESC P Device Control String ( DCS is 0x90). - case 'P': - this.params = []; - this.currentParam = 0; - this.state = dcs; - break; - // ESC _ Application Program Command ( APC is 0x9f). - case '_': - this.state = ignore; - break; - // ESC ^ Privacy Message ( PM is 0x9e). - case '^': - this.state = ignore; - break; - // ESC c Full Reset (RIS). - case 'c': - this.reset(); - break; - // ESC E Next Line ( NEL is 0x85). - // ESC D Index ( IND is 0x84). - case 'E': - this.x = 0; - ; - case 'D': - this.index(); - break; - // ESC M Reverse Index ( RI is 0x8d). - case 'M': - this.reverseIndex(); - break; - // ESC % Select default/utf-8 character set. - // @ = default, G = utf-8 - case '%': - //this.charset = null; - this.setgLevel(0); - this.setgCharset(0, Terminal.charsets.US); - this.state = normal; - i++; - break; - // ESC (,),*,+,-,. Designate G0-G2 Character Set. - case '(': // <-- this seems to get all the attention - case ')': - case '*': - case '+': - case '-': - case '.': - switch (ch) { - case '(': - this.gcharset = 0; - break; - case ')': - this.gcharset = 1; - break; - case '*': - this.gcharset = 2; - break; - case '+': - this.gcharset = 3; - break; - case '-': - this.gcharset = 1; - break; - case '.': - this.gcharset = 2; - break; - } - this.state = charset; - break; - // Designate G3 Character Set (VT300). - // A = ISO Latin-1 Supplemental. - // Not implemented. - case '/': - this.gcharset = 3; - this.state = charset; - i--; - break; - // ESC N - // Single Shift Select of G2 Character Set - // ( SS2 is 0x8e). This affects next character only. - case 'N': - break; - // ESC O - // Single Shift Select of G3 Character Set - // ( SS3 is 0x8f). This affects next character only. - case 'O': - break; - // ESC n - // Invoke the G2 Character Set as GL (LS2). - case 'n': - this.setgLevel(2); - break; - // ESC o - // Invoke the G3 Character Set as GL (LS3). - case 'o': - this.setgLevel(3); - break; - // ESC | - // Invoke the G3 Character Set as GR (LS3R). - case '|': - this.setgLevel(3); - break; - // ESC } - // Invoke the G2 Character Set as GR (LS2R). - case '}': - this.setgLevel(2); - break; - // ESC ~ - // Invoke the G1 Character Set as GR (LS1R). - case '~': - this.setgLevel(1); - break; - // ESC 7 Save Cursor (DECSC). - case '7': - this.saveCursor(); - this.state = normal; - break; - // ESC 8 Restore Cursor (DECRC). - case '8': - this.restoreCursor(); - this.state = normal; - break; - // ESC # 3 DEC line height/width - case '#': - this.state = normal; - i++; - break; - // ESC H Tab Set (HTS is 0x88). - case 'H': - this.tabSet(); - break; - // ESC = Application Keypad (DECKPAM). - case '=': - this.log('Serial port requested application keypad.'); - this.applicationKeypad = true; - this.viewport.syncScrollArea(); - this.state = normal; - break; - // ESC > Normal Keypad (DECKPNM). - case '>': - this.log('Switching back to normal keypad.'); - this.applicationKeypad = false; - this.viewport.syncScrollArea(); - this.state = normal; - break; - default: - this.state = normal; - this.error('Unknown ESC control: %s.', ch); - break; - } - break; - case charset: - switch (ch) { - case '0': - cs = Terminal.charsets.SCLD; - break; - case 'A': - cs = Terminal.charsets.UK; - break; - case 'B': - cs = Terminal.charsets.US; - break; - case '4': - cs = Terminal.charsets.Dutch; - break; - case 'C': // Finnish - case '5': - cs = Terminal.charsets.Finnish; - break; - case 'R': - cs = Terminal.charsets.French; - break; - case 'Q': - cs = Terminal.charsets.FrenchCanadian; - break; - case 'K': - cs = Terminal.charsets.German; - break; - case 'Y': - cs = Terminal.charsets.Italian; - break; - case 'E': // NorwegianDanish - case '6': - cs = Terminal.charsets.NorwegianDanish; - break; - case 'Z': - cs = Terminal.charsets.Spanish; - break; - case 'H': // Swedish - case '7': - cs = Terminal.charsets.Swedish; - break; - case '=': - cs = Terminal.charsets.Swiss; - break; - case '/': - cs = Terminal.charsets.ISOLatin; - i++; - break; - default: - cs = Terminal.charsets.US; - break; - } - this.setgCharset(this.gcharset, cs); - this.gcharset = null; - this.state = normal; - break; - case osc: - // OSC Ps ; Pt ST - // OSC Ps ; Pt BEL - // Set Text Parameters. - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') - i++; - this.params.push(this.currentParam); - switch (this.params[0]) { - case 0: - case 1: - case 2: - if (this.params[1]) { - this.title = this.params[1]; - this.handleTitle(this.title); - } - break; - case 3: - // set X property - break; - case 4: - case 5: - // change dynamic colors - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - // change dynamic ui colors - break; - case 46: - // change log file - break; - case 50: - // dynamic font - break; - case 51: - // emacs shell - break; - case 52: - // manipulate selection data - break; - case 104: - case 105: - case 110: - case 111: - case 112: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: - // reset colors - break; - } - this.params = []; - this.currentParam = 0; - this.state = normal; - } - else { - if (!this.params.length) { - if (ch >= '0' && ch <= '9') { - this.currentParam = - this.currentParam * 10 + ch.charCodeAt(0) - 48; - } - else if (ch === ';') { - this.params.push(this.currentParam); - this.currentParam = ''; - } - } - else { - this.currentParam += ch; - } - } - break; - case csi: - // '?', '>', '!' - if (ch === '?' || ch === '>' || ch === '!') { - this.prefix = ch; - break; - } - // 0 - 9 - if (ch >= '0' && ch <= '9') { - this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; - break; - } - // '$', '"', ' ', '\'' - if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { - this.postfix = ch; - break; - } - this.params.push(this.currentParam); - this.currentParam = 0; - // ';' - if (ch === ';') - break; - this.state = normal; - switch (ch) { - // CSI Ps A - // Cursor Up Ps Times (default = 1) (CUU). - case 'A': - this.cursorUp(this.params); - break; - // CSI Ps B - // Cursor Down Ps Times (default = 1) (CUD). - case 'B': - this.cursorDown(this.params); - break; - // CSI Ps C - // Cursor Forward Ps Times (default = 1) (CUF). - case 'C': - this.cursorForward(this.params); - break; - // CSI Ps D - // Cursor Backward Ps Times (default = 1) (CUB). - case 'D': - this.cursorBackward(this.params); - break; - // CSI Ps ; Ps H - // Cursor Position [row;column] (default = [1,1]) (CUP). - case 'H': - this.cursorPos(this.params); - break; - // CSI Ps J Erase in Display (ED). - case 'J': - this.eraseInDisplay(this.params); - break; - // CSI Ps K Erase in Line (EL). - case 'K': - this.eraseInLine(this.params); - break; - // CSI Pm m Character Attributes (SGR). - case 'm': - if (!this.prefix) { - this.charAttributes(this.params); - } - break; - // CSI Ps n Device Status Report (DSR). - case 'n': - if (!this.prefix) { - this.deviceStatus(this.params); - } - break; - /** - * Additions - */ - // CSI Ps @ - // Insert Ps (Blank) Character(s) (default = 1) (ICH). - case '@': - this.insertChars(this.params); - break; - // CSI Ps E - // Cursor Next Line Ps Times (default = 1) (CNL). - case 'E': - this.cursorNextLine(this.params); - break; - // CSI Ps F - // Cursor Preceding Line Ps Times (default = 1) (CNL). - case 'F': - this.cursorPrecedingLine(this.params); - break; - // CSI Ps G - // Cursor Character Absolute [column] (default = [row,1]) (CHA). - case 'G': - this.cursorCharAbsolute(this.params); - break; - // CSI Ps L - // Insert Ps Line(s) (default = 1) (IL). - case 'L': - this.insertLines(this.params); - break; - // CSI Ps M - // Delete Ps Line(s) (default = 1) (DL). - case 'M': - this.deleteLines(this.params); - break; - // CSI Ps P - // Delete Ps Character(s) (default = 1) (DCH). - case 'P': - this.deleteChars(this.params); - break; - // CSI Ps X - // Erase Ps Character(s) (default = 1) (ECH). - case 'X': - this.eraseChars(this.params); - break; - // CSI Pm ` Character Position Absolute - // [column] (default = [row,1]) (HPA). - case '`': - this.charPosAbsolute(this.params); - break; - // 141 61 a * HPR - - // Horizontal Position Relative - case 'a': - this.HPositionRelative(this.params); - break; - // CSI P s c - // Send Device Attributes (Primary DA). - // CSI > P s c - // Send Device Attributes (Secondary DA) - case 'c': - this.sendDeviceAttributes(this.params); - break; - // CSI Pm d - // Line Position Absolute [row] (default = [1,column]) (VPA). - case 'd': - this.linePosAbsolute(this.params); - break; - // 145 65 e * VPR - Vertical Position Relative - case 'e': - this.VPositionRelative(this.params); - break; - // CSI Ps ; Ps f - // Horizontal and Vertical Position [row;column] (default = - // [1,1]) (HVP). - case 'f': - this.HVPosition(this.params); - break; - // CSI Pm h Set Mode (SM). - // CSI ? Pm h - mouse escape codes, cursor escape codes - case 'h': - this.setMode(this.params); - break; - // CSI Pm l Reset Mode (RM). - // CSI ? Pm l - case 'l': - this.resetMode(this.params); - break; - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - case 'r': - this.setScrollRegion(this.params); - break; - // CSI s - // Save cursor (ANSI.SYS). - case 's': - this.saveCursor(this.params); - break; - // CSI u - // Restore cursor (ANSI.SYS). - case 'u': - this.restoreCursor(this.params); - break; - /** - * Lesser Used - */ - // CSI Ps I - // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). - case 'I': - this.cursorForwardTab(this.params); - break; - // CSI Ps S Scroll up Ps lines (default = 1) (SU). - case 'S': - this.scrollUp(this.params); - break; - // CSI Ps T Scroll down Ps lines (default = 1) (SD). - // CSI Ps ; Ps ; Ps ; Ps ; Ps T - // CSI > Ps; Ps T - case 'T': - // if (this.prefix === '>') { - // this.resetTitleModes(this.params); - // break; - // } - // if (this.params.length > 2) { - // this.initMouseTracking(this.params); - // break; - // } - if (this.params.length < 2 && !this.prefix) { - this.scrollDown(this.params); - } - break; - // CSI Ps Z - // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). - case 'Z': - this.cursorBackwardTab(this.params); - break; - // CSI Ps b Repeat the preceding graphic character Ps times (REP). - case 'b': - this.repeatPrecedingCharacter(this.params); - break; - // CSI Ps g Tab Clear (TBC). - case 'g': - this.tabClear(this.params); - break; - // CSI Pm i Media Copy (MC). - // CSI ? Pm i - // case 'i': - // this.mediaCopy(this.params); - // break; - // CSI Pm m Character Attributes (SGR). - // CSI > Ps; Ps m - // case 'm': // duplicate - // if (this.prefix === '>') { - // this.setResources(this.params); - // } else { - // this.charAttributes(this.params); - // } - // break; - // CSI Ps n Device Status Report (DSR). - // CSI > Ps n - // case 'n': // duplicate - // if (this.prefix === '>') { - // this.disableModifiers(this.params); - // } else { - // this.deviceStatus(this.params); - // } - // break; - // CSI > Ps p Set pointer mode. - // CSI ! p Soft terminal reset (DECSTR). - // CSI Ps$ p - // Request ANSI mode (DECRQM). - // CSI ? Ps$ p - // Request DEC private mode (DECRQM). - // CSI Ps ; Ps " p - case 'p': - switch (this.prefix) { - // case '>': - // this.setPointerMode(this.params); - // break; - case '!': - this.softReset(this.params); - break; - } - break; - // CSI Ps q Load LEDs (DECLL). - // CSI Ps SP q - // CSI Ps " q - // case 'q': - // if (this.postfix === ' ') { - // this.setCursorStyle(this.params); - // break; - // } - // if (this.postfix === '"') { - // this.setCharProtectionAttr(this.params); - // break; - // } - // this.loadLEDs(this.params); - // break; - // CSI Ps ; Ps r - // Set Scrolling Region [top;bottom] (default = full size of win- - // dow) (DECSTBM). - // CSI ? Pm r - // CSI Pt; Pl; Pb; Pr; Ps$ r - // case 'r': // duplicate - // if (this.prefix === '?') { - // this.restorePrivateValues(this.params); - // } else if (this.postfix === '$') { - // this.setAttrInRectangle(this.params); - // } else { - // this.setScrollRegion(this.params); - // } - // break; - // CSI s Save cursor (ANSI.SYS). - // CSI ? Pm s - // case 's': // duplicate - // if (this.prefix === '?') { - // this.savePrivateValues(this.params); - // } else { - // this.saveCursor(this.params); - // } - // break; - // CSI Ps ; Ps ; Ps t - // CSI Pt; Pl; Pb; Pr; Ps$ t - // CSI > Ps; Ps t - // CSI Ps SP t - // case 't': - // if (this.postfix === '$') { - // this.reverseAttrInRectangle(this.params); - // } else if (this.postfix === ' ') { - // this.setWarningBellVolume(this.params); - // } else { - // if (this.prefix === '>') { - // this.setTitleModeFeature(this.params); - // } else { - // this.manipulateWindow(this.params); - // } - // } - // break; - // CSI u Restore cursor (ANSI.SYS). - // CSI Ps SP u - // case 'u': // duplicate - // if (this.postfix === ' ') { - // this.setMarginBellVolume(this.params); - // } else { - // this.restoreCursor(this.params); - // } - // break; - // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v - // case 'v': - // if (this.postfix === '$') { - // this.copyRectagle(this.params); - // } - // break; - // CSI Pt ; Pl ; Pb ; Pr ' w - // case 'w': - // if (this.postfix === '\'') { - // this.enableFilterRectangle(this.params); - // } - // break; - // CSI Ps x Request Terminal Parameters (DECREQTPARM). - // CSI Ps x Select Attribute Change Extent (DECSACE). - // CSI Pc; Pt; Pl; Pb; Pr$ x - // case 'x': - // if (this.postfix === '$') { - // this.fillRectangle(this.params); - // } else { - // this.requestParameters(this.params); - // //this.__(this.params); - // } - // break; - // CSI Ps ; Pu ' z - // CSI Pt; Pl; Pb; Pr$ z - // case 'z': - // if (this.postfix === '\'') { - // this.enableLocatorReporting(this.params); - // } else if (this.postfix === '$') { - // this.eraseRectangle(this.params); - // } - // break; - // CSI Pm ' { - // CSI Pt; Pl; Pb; Pr$ { - // case '{': - // if (this.postfix === '\'') { - // this.setLocatorEvents(this.params); - // } else if (this.postfix === '$') { - // this.selectiveEraseRectangle(this.params); - // } - // break; - // CSI Ps ' | - // case '|': - // if (this.postfix === '\'') { - // this.requestLocatorPosition(this.params); - // } - // break; - // CSI P m SP } - // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. - // case '}': - // if (this.postfix === ' ') { - // this.insertColumns(this.params); - // } - // break; - // CSI P m SP ~ - // Delete P s Column(s) (default = 1) (DECDC), VT420 and up - // case '~': - // if (this.postfix === ' ') { - // this.deleteColumns(this.params); - // } - // break; - default: - this.error('Unknown CSI code: %s.', ch); - break; - } - this.prefix = ''; - this.postfix = ''; - break; - case dcs: - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') - i++; - switch (this.prefix) { - // User-Defined Keys (DECUDK). - case '': - break; - // Request Status String (DECRQSS). - // test: echo -e '\eP$q"p\e\\' - case '$q': - var pt = this.currentParam, valid = false; - switch (pt) { - // DECSCA - case '"q': - pt = '0"q'; - break; - // DECSCL - case '"p': - pt = '61"p'; - break; - // DECSTBM - case 'r': - pt = '' - + (this.scrollTop + 1) - + ';' - + (this.scrollBottom + 1) - + 'r'; - break; - // SGR - case 'm': - pt = '0m'; - break; - default: - this.error('Unknown DCS Pt: %s.', pt); - pt = ''; - break; - } - this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\'); - break; - // Set Termcap/Terminfo Data (xterm, experimental). - case '+p': - break; - // Request Termcap/Terminfo String (xterm, experimental) - // Regular xterm does not even respond to this sequence. - // This can cause a small glitch in vim. - // test: echo -ne '\eP+q6b64\e\\' - case '+q': - var pt = this.currentParam, valid = false; - this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\'); - break; - default: - this.error('Unknown DCS prefix: %s.', this.prefix); - break; - } - this.currentParam = 0; - this.prefix = ''; - this.state = normal; - } - else if (!this.currentParam) { - if (!this.prefix && ch !== '$' && ch !== '+') { - this.currentParam = ch; - } - else if (this.prefix.length === 2) { - this.currentParam = ch; - } - else { - this.prefix += ch; - } - } - else { - this.currentParam += ch; - } - break; - case ignore: - // For PM and APC. - if (ch === '\x1b' || ch === '\x07') { - if (ch === '\x1b') - i++; - this.state = normal; - } - break; - } - } - this.updateRange(this.y); - this.refresh(this.refreshStart, this.refreshEnd); -}; -/** - * Writes text to the terminal, followed by a break line character (\n). - * @param {string} text The text to write to the terminal. - */ -Terminal.prototype.writeln = function (data) { - this.write(data + '\r\n'); -}; -/** - * Attaches a custom keydown handler which is run before keys are processed, giving consumers of - * xterm.js ultimate control as to what keys should be processed by the terminal and what keys - * should not. - * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a - * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent - * the default action. The function returns whether the event should be processed by xterm.js. - */ -Terminal.prototype.attachCustomKeydownHandler = function (customKeydownHandler) { - this.customKeydownHandler = customKeydownHandler; -}; -/** - * Handle a keydown event - * Key Resources: - * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent - * @param {KeyboardEvent} ev The keydown event to be handled. - */ -Terminal.prototype.keyDown = function (ev) { - if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) { - return false; - } - if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { - if (this.ybase !== this.ydisp) { - this.scrollToBottom(); - } - return false; - } - var self = this; - var result = this.evaluateKeyEscapeSequence(ev); - if (result.scrollDisp) { - this.scrollDisp(result.scrollDisp); - return this.cancel(ev, true); - } - if (isThirdLevelShift(this, ev)) { - return true; - } - if (result.cancel) { - // The event is canceled at the end already, is this necessary? - this.cancel(ev, true); - } - if (!result.key) { - return true; - } - this.emit('keydown', ev); - this.emit('key', result.key, ev); - this.showCursor(); - this.handler(result.key); - return this.cancel(ev, true); -}; -/** - * Returns an object that determines how a KeyboardEvent should be handled. The key of the - * returned value is the new key code to pass to the PTY. - * - * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html - * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence. - */ -Terminal.prototype.evaluateKeyEscapeSequence = function (ev) { - var result = { - // Whether to cancel event propogation (NOTE: this may not be needed since the event is - // canceled at the end of keyDown - cancel: false, - // The new key even to emit - key: undefined, - // The number of characters to scroll, if this is defined it will cancel the event - scrollDisp: undefined - }; - var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3; - switch (ev.keyCode) { - case 8: - // backspace - if (ev.shiftKey) { - result.key = '\x08'; // ^H - break; - } - result.key = '\x7f'; // ^? - break; - case 9: - // tab - if (ev.shiftKey) { - result.key = '\x1b[Z'; - break; - } - result.key = '\t'; - result.cancel = true; - break; - case 13: - // return/enter - result.key = '\r'; - result.cancel = true; - break; - case 27: - // escape - result.key = '\x1b'; - result.cancel = true; - break; - case 37: - // left-arrow - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'D'; - // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards - // http://unix.stackexchange.com/a/108106 - if (result.key == '\x1b[1;3D') { - result.key = '\x1b[1;5D'; - } - } - else if (this.applicationCursor) { - result.key = '\x1bOD'; - } - else { - result.key = '\x1b[D'; - } - break; - case 39: - // right-arrow - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'C'; - // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward - // http://unix.stackexchange.com/a/108106 - if (result.key == '\x1b[1;3C') { - result.key = '\x1b[1;5C'; - } - } - else if (this.applicationCursor) { - result.key = '\x1bOC'; - } - else { - result.key = '\x1b[C'; - } - break; - case 38: - // up-arrow - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'A'; - // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow - // http://unix.stackexchange.com/a/108106 - if (result.key == '\x1b[1;3A') { - result.key = '\x1b[1;5A'; - } - } - else if (this.applicationCursor) { - result.key = '\x1bOA'; - } - else { - result.key = '\x1b[A'; - } - break; - case 40: - // down-arrow - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'B'; - // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow - // http://unix.stackexchange.com/a/108106 - if (result.key == '\x1b[1;3B') { - result.key = '\x1b[1;5B'; - } - } - else if (this.applicationCursor) { - result.key = '\x1bOB'; - } - else { - result.key = '\x1b[B'; - } - break; - case 45: - // insert - if (!ev.shiftKey && !ev.ctrlKey) { - // or + are used to - // copy-paste on some systems. - result.key = '\x1b[2~'; - } - break; - case 46: - // delete - if (modifiers) { - result.key = '\x1b[3;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[3~'; - } - break; - case 36: - // home - if (modifiers) - result.key = '\x1b[1;' + (modifiers + 1) + 'H'; - else if (this.applicationCursor) - result.key = '\x1bOH'; - else - result.key = '\x1b[H'; - break; - case 35: - // end - if (modifiers) - result.key = '\x1b[1;' + (modifiers + 1) + 'F'; - else if (this.applicationCursor) - result.key = '\x1bOF'; - else - result.key = '\x1b[F'; - break; - case 33: - // page up - if (ev.shiftKey) { - result.scrollDisp = -(this.rows - 1); - } - else { - result.key = '\x1b[5~'; - } - break; - case 34: - // page down - if (ev.shiftKey) { - result.scrollDisp = this.rows - 1; - } - else { - result.key = '\x1b[6~'; - } - break; - case 112: - // F1-F12 - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'P'; - } - else { - result.key = '\x1bOP'; - } - break; - case 113: - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'Q'; - } - else { - result.key = '\x1bOQ'; - } - break; - case 114: - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'R'; - } - else { - result.key = '\x1bOR'; - } - break; - case 115: - if (modifiers) { - result.key = '\x1b[1;' + (modifiers + 1) + 'S'; - } - else { - result.key = '\x1bOS'; - } - break; - case 116: - if (modifiers) { - result.key = '\x1b[15;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[15~'; - } - break; - case 117: - if (modifiers) { - result.key = '\x1b[17;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[17~'; - } - break; - case 118: - if (modifiers) { - result.key = '\x1b[18;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[18~'; - } - break; - case 119: - if (modifiers) { - result.key = '\x1b[19;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[19~'; - } - break; - case 120: - if (modifiers) { - result.key = '\x1b[20;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[20~'; - } - break; - case 121: - if (modifiers) { - result.key = '\x1b[21;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[21~'; - } - break; - case 122: - if (modifiers) { - result.key = '\x1b[23;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[23~'; - } - break; - case 123: - if (modifiers) { - result.key = '\x1b[24;' + (modifiers + 1) + '~'; - } - else { - result.key = '\x1b[24~'; - } - break; - default: - // a-z and space - if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) { - if (ev.keyCode >= 65 && ev.keyCode <= 90) { - result.key = String.fromCharCode(ev.keyCode - 64); - } - else if (ev.keyCode === 32) { - // NUL - result.key = String.fromCharCode(0); - } - else if (ev.keyCode >= 51 && ev.keyCode <= 55) { - // escape, file sep, group sep, record sep, unit sep - result.key = String.fromCharCode(ev.keyCode - 51 + 27); - } - else if (ev.keyCode === 56) { - // delete - result.key = String.fromCharCode(127); - } - else if (ev.keyCode === 219) { - // ^[ - Control Sequence Introducer (CSI) - result.key = String.fromCharCode(27); - } - else if (ev.keyCode === 220) { - // ^\ - String Terminator (ST) - result.key = String.fromCharCode(28); - } - else if (ev.keyCode === 221) { - // ^] - Operating System Command (OSC) - result.key = String.fromCharCode(29); - } - } - else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { - // On Mac this is a third level shift. Use instead. - if (ev.keyCode >= 65 && ev.keyCode <= 90) { - result.key = '\x1b' + String.fromCharCode(ev.keyCode + 32); - } - else if (ev.keyCode === 192) { - result.key = '\x1b`'; - } - else if (ev.keyCode >= 48 && ev.keyCode <= 57) { - result.key = '\x1b' + (ev.keyCode - 48); - } - } - break; - } - return result; -}; -/** - * Set the G level of the terminal - * @param g - */ -Terminal.prototype.setgLevel = function (g) { - this.glevel = g; - this.charset = this.charsets[g]; -}; -/** - * Set the charset for the given G level of the terminal - * @param g - * @param charset - */ -Terminal.prototype.setgCharset = function (g, charset) { - this.charsets[g] = charset; - if (this.glevel === g) { - this.charset = charset; - } -}; -/** - * Handle a keypress event. - * Key Resources: - * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent - * @param {KeyboardEvent} ev The keypress event to be handled. - */ -Terminal.prototype.keyPress = function (ev) { - var key; - this.cancel(ev); - if (ev.charCode) { - key = ev.charCode; - } - else if (ev.which == null) { - key = ev.keyCode; - } - else if (ev.which !== 0 && ev.charCode !== 0) { - key = ev.which; - } - else { - return false; - } - if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev))) { - return false; - } - key = String.fromCharCode(key); - this.emit('keypress', key, ev); - this.emit('key', key, ev); - this.showCursor(); - this.handler(key); - return false; -}; -/** - * Send data for handling to the terminal - * @param {string} data - */ -Terminal.prototype.send = function (data) { - var self = this; - if (!this.queue) { - setTimeout(function () { - self.handler(self.queue); - self.queue = ''; - }, 1); - } - this.queue += data; -}; -/** - * Ring the bell. - * Note: We could do sweet things with webaudio here - */ -Terminal.prototype.bell = function () { - if (!this.visualBell) - return; - var self = this; - this.element.style.borderColor = 'white'; - setTimeout(function () { - self.element.style.borderColor = ''; - }, 10); - if (this.popOnBell) - this.focus(); -}; -/** - * Log the current state to the console. - */ -Terminal.prototype.log = function () { - if (!this.debug) - return; - if (!this.context.console || !this.context.console.log) - return; - var args = Array.prototype.slice.call(arguments); - this.context.console.log.apply(this.context.console, args); -}; -/** - * Log the current state as error to the console. - */ -Terminal.prototype.error = function () { - if (!this.debug) - return; - if (!this.context.console || !this.context.console.error) - return; - var args = Array.prototype.slice.call(arguments); - this.context.console.error.apply(this.context.console, args); -}; -/** - * Resizes the terminal. - * - * @param {number} x The number of columns to resize to. - * @param {number} y The number of rows to resize to. - */ -Terminal.prototype.resize = function (x, y) { - var line, el, i, j, ch, addToY; - if (x === this.cols && y === this.rows) { - return; - } - if (x < 1) - x = 1; - if (y < 1) - y = 1; - // resize cols - j = this.cols; - if (j < x) { - ch = [this.defAttr, ' ', 1]; // does xterm use the default attr? - i = this.lines.length; - while (i--) { - while (this.lines[i].length < x) { - this.lines[i].push(ch); - } - } - } - else { - i = this.lines.length; - while (i--) { - while (this.lines[i].length > x) { - this.lines[i].pop(); - } - } - } - this.setupStops(j); - this.cols = x; - // resize rows - j = this.rows; - addToY = 0; - if (j < y) { - el = this.element; - while (j++ < y) { - // y is rows, not this.y - if (this.lines.length < y + this.ybase) { - if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) { - // There is room above the buffer and there are no empty elements below the line, - // scroll up - this.ybase--; - addToY++; - if (this.ydisp > 0) { - // Viewport is at the top of the buffer, must increase downwards - this.ydisp--; - } - } - else { - // Add a blank line if there is no buffer left at the top to scroll to, or if there - // are blank lines after the cursor - this.lines.push(this.blankLine()); - } - } - if (this.children.length < y) { - this.insertRow(); - } - } - } - else { - while (j-- > y) { - if (this.lines.length > y + this.ybase) { - if (this.lines.length > this.ybase + this.y + 1) { - // The line is a blank line below the cursor, remove it - this.lines.pop(); - } - else { - // The line is the cursor, scroll down - this.ybase++; - this.ydisp++; - } - } - if (this.children.length > y) { - el = this.children.shift(); - if (!el) - continue; - el.parentNode.removeChild(el); - } - } - } - this.rows = y; - // Make sure that the cursor stays on screen - if (this.y >= y) { - this.y = y - 1; - } - if (addToY) { - this.y += addToY; - } - if (this.x >= x) { - this.x = x - 1; - } - this.scrollTop = 0; - this.scrollBottom = y - 1; - this.refresh(0, this.rows - 1); - this.normal = null; - this.geometry = [this.cols, this.rows]; - this.emit('resize', { terminal: this, cols: x, rows: y }); -}; -/** - * Updates the range of rows to refresh - * @param {number} y The number of rows to refresh next. - */ -Terminal.prototype.updateRange = function (y) { - if (y < this.refreshStart) - this.refreshStart = y; - if (y > this.refreshEnd) - this.refreshEnd = y; - // if (y > this.refreshEnd) { - // this.refreshEnd = y; - // if (y > this.rows - 1) { - // this.refreshEnd = this.rows - 1; - // } - // } -}; -/** - * Set the range of refreshing to the maximum value - */ -Terminal.prototype.maxRange = function () { - this.refreshStart = 0; - this.refreshEnd = this.rows - 1; -}; -/** - * Setup the tab stops. - * @param {number} i - */ -Terminal.prototype.setupStops = function (i) { - if (i != null) { - if (!this.tabs[i]) { - i = this.prevStop(i); - } - } - else { - this.tabs = {}; - i = 0; - } - for (; i < this.cols; i += 8) { - this.tabs[i] = true; - } -}; -/** - * Move the cursor to the previous tab stop from the given position (default is current). - * @param {number} x The position to move the cursor to the previous tab stop. - */ -Terminal.prototype.prevStop = function (x) { - if (x == null) - x = this.x; - while (!this.tabs[--x] && x > 0) - ; - return x >= this.cols - ? this.cols - 1 - : x < 0 ? 0 : x; -}; -/** - * Move the cursor one tab stop forward from the given position (default is current). - * @param {number} x The position to move the cursor one tab stop forward. - */ -Terminal.prototype.nextStop = function (x) { - if (x == null) - x = this.x; - while (!this.tabs[++x] && x < this.cols) - ; - return x >= this.cols - ? this.cols - 1 - : x < 0 ? 0 : x; -}; -/** - * Erase in the identified line everything from "x" to the end of the line (right). - * @param {number} x The column from which to start erasing to the end of the line. - * @param {number} y The line in which to operate. - */ -Terminal.prototype.eraseRight = function (x, y) { - var line = this.lines[this.ybase + y], ch = [this.eraseAttr(), ' ', 1]; // xterm - for (; x < this.cols; x++) { - line[x] = ch; - } - this.updateRange(y); -}; -/** - * Erase in the identified line everything from "x" to the start of the line (left). - * @param {number} x The column from which to start erasing to the start of the line. - * @param {number} y The line in which to operate. - */ -Terminal.prototype.eraseLeft = function (x, y) { - var line = this.lines[this.ybase + y], ch = [this.eraseAttr(), ' ', 1]; // xterm - x++; - while (x--) - line[x] = ch; - this.updateRange(y); -}; -/** - * Clears the entire buffer, making the prompt line the new first line. - */ -Terminal.prototype.clear = function () { - if (this.ybase === 0 && this.y === 0) { - // Don't clear if it's already clear - return; - } - this.lines = [this.lines[this.ybase + this.y]]; - this.ydisp = 0; - this.ybase = 0; - this.y = 0; - for (var i = 1; i < this.rows; i++) { - this.lines.push(this.blankLine()); - } - this.refresh(0, this.rows - 1); - this.emit('scroll', this.ydisp); -}; -/** - * Erase all content in the given line - * @param {number} y The line to erase all of its contents. - */ -Terminal.prototype.eraseLine = function (y) { - this.eraseRight(0, y); -}; -/** - * Return the data array of a blank line/ - * @param {number} cur First bunch of data for each "blank" character. - */ -Terminal.prototype.blankLine = function (cur) { - var attr = cur - ? this.eraseAttr() - : this.defAttr; - var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character - , line = [], i = 0; - for (; i < this.cols; i++) { - line[i] = ch; - } - return line; -}; -/** - * If cur return the back color xterm feature attribute. Else return defAttr. - * @param {object} cur - */ -Terminal.prototype.ch = function (cur) { - return cur - ? [this.eraseAttr(), ' ', 1] - : [this.defAttr, ' ', 1]; -}; -/** - * Evaluate if the current erminal is the given argument. - * @param {object} term The terminal to evaluate - */ -Terminal.prototype.is = function (term) { - var name = this.termName; - return (name + '').indexOf(term) === 0; -}; -/** - * Emit the 'data' event and populate the given data. - * @param {string} data The data to populate in the event. - */ -Terminal.prototype.handler = function (data) { - // Input is being sent to the terminal, the terminal should focus the prompt. - if (this.ybase !== this.ydisp) { - this.scrollToBottom(); - } - this.emit('data', data); -}; -/** - * Emit the 'title' event and populate the given title. - * @param {string} title The title to populate in the event. - */ -Terminal.prototype.handleTitle = function (title) { - /** - * This event is emitted when the title of the terminal is changed - * from inside the terminal. The parameter is the new title. - * - * @event title - */ - this.emit('title', title); -}; -/** - * ESC - */ -/** - * ESC D Index (IND is 0x84). - */ -Terminal.prototype.index = function () { - this.y++; - if (this.y > this.scrollBottom) { - this.y--; - this.scroll(); - } - this.state = normal; -}; -/** - * ESC M Reverse Index (RI is 0x8d). - */ -Terminal.prototype.reverseIndex = function () { - var j; - this.y--; - if (this.y < this.scrollTop) { - this.y++; - // possibly move the code below to term.reverseScroll(); - // test: echo -ne '\e[1;1H\e[44m\eM\e[0m' - // blankLine(true) is xterm/linux behavior - this.lines.splice(this.y + this.ybase, 0, this.blankLine(true)); - j = this.rows - 1 - this.scrollBottom; - this.lines.splice(this.rows - 1 + this.ybase - j + 1, 1); - // this.maxRange(); - this.updateRange(this.scrollTop); - this.updateRange(this.scrollBottom); - } - this.state = normal; -}; -/** - * ESC c Full Reset (RIS). - */ -Terminal.prototype.reset = function () { - this.options.rows = this.rows; - this.options.cols = this.cols; - var customKeydownHandler = this.customKeydownHandler; - Terminal.call(this, this.options); - this.customKeydownHandler = customKeydownHandler; - this.refresh(0, this.rows - 1); - this.viewport.syncScrollArea(); -}; -/** - * ESC H Tab Set (HTS is 0x88). - */ -Terminal.prototype.tabSet = function () { - this.tabs[this.x] = true; - this.state = normal; -}; -/** - * CSI - */ -/** - * CSI Ps A - * Cursor Up Ps Times (default = 1) (CUU). - */ -Terminal.prototype.cursorUp = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.y -= param; - if (this.y < 0) - this.y = 0; -}; -/** - * CSI Ps B - * Cursor Down Ps Times (default = 1) (CUD). - */ -Terminal.prototype.cursorDown = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.y += param; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } -}; -/** - * CSI Ps C - * Cursor Forward Ps Times (default = 1) (CUF). - */ -Terminal.prototype.cursorForward = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.x += param; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; -/** - * CSI Ps D - * Cursor Backward Ps Times (default = 1) (CUB). - */ -Terminal.prototype.cursorBackward = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.x -= param; - if (this.x < 0) - this.x = 0; -}; -/** - * CSI Ps ; Ps H - * Cursor Position [row;column] (default = [1,1]) (CUP). - */ -Terminal.prototype.cursorPos = function (params) { - var row, col; - row = params[0] - 1; - if (params.length >= 2) { - col = params[1] - 1; - } - else { - col = 0; - } - if (row < 0) { - row = 0; - } - else if (row >= this.rows) { - row = this.rows - 1; - } - if (col < 0) { - col = 0; - } - else if (col >= this.cols) { - col = this.cols - 1; - } - this.x = col; - this.y = row; -}; -/** - * CSI Ps J Erase in Display (ED). - * Ps = 0 -> Erase Below (default). - * Ps = 1 -> Erase Above. - * Ps = 2 -> Erase All. - * Ps = 3 -> Erase Saved Lines (xterm). - * CSI ? Ps J - * Erase in Display (DECSED). - * Ps = 0 -> Selective Erase Below (default). - * Ps = 1 -> Selective Erase Above. - * Ps = 2 -> Selective Erase All. - */ -Terminal.prototype.eraseInDisplay = function (params) { - var j; - switch (params[0]) { - case 0: - this.eraseRight(this.x, this.y); - j = this.y + 1; - for (; j < this.rows; j++) { - this.eraseLine(j); - } - break; - case 1: - this.eraseLeft(this.x, this.y); - j = this.y; - while (j--) { - this.eraseLine(j); - } - break; - case 2: - j = this.rows; - while (j--) - this.eraseLine(j); - break; - case 3: - ; // no saved lines - break; - } -}; -/** - * CSI Ps K Erase in Line (EL). - * Ps = 0 -> Erase to Right (default). - * Ps = 1 -> Erase to Left. - * Ps = 2 -> Erase All. - * CSI ? Ps K - * Erase in Line (DECSEL). - * Ps = 0 -> Selective Erase to Right (default). - * Ps = 1 -> Selective Erase to Left. - * Ps = 2 -> Selective Erase All. - */ -Terminal.prototype.eraseInLine = function (params) { - switch (params[0]) { - case 0: - this.eraseRight(this.x, this.y); - break; - case 1: - this.eraseLeft(this.x, this.y); - break; - case 2: - this.eraseLine(this.y); - break; - } -}; -/** - * CSI Pm m Character Attributes (SGR). - * Ps = 0 -> Normal (default). - * Ps = 1 -> Bold. - * Ps = 4 -> Underlined. - * Ps = 5 -> Blink (appears as Bold). - * Ps = 7 -> Inverse. - * Ps = 8 -> Invisible, i.e., hidden (VT300). - * Ps = 2 2 -> Normal (neither bold nor faint). - * Ps = 2 4 -> Not underlined. - * Ps = 2 5 -> Steady (not blinking). - * Ps = 2 7 -> Positive (not inverse). - * Ps = 2 8 -> Visible, i.e., not hidden (VT300). - * Ps = 3 0 -> Set foreground color to Black. - * Ps = 3 1 -> Set foreground color to Red. - * Ps = 3 2 -> Set foreground color to Green. - * Ps = 3 3 -> Set foreground color to Yellow. - * Ps = 3 4 -> Set foreground color to Blue. - * Ps = 3 5 -> Set foreground color to Magenta. - * Ps = 3 6 -> Set foreground color to Cyan. - * Ps = 3 7 -> Set foreground color to White. - * Ps = 3 9 -> Set foreground color to default (original). - * Ps = 4 0 -> Set background color to Black. - * Ps = 4 1 -> Set background color to Red. - * Ps = 4 2 -> Set background color to Green. - * Ps = 4 3 -> Set background color to Yellow. - * Ps = 4 4 -> Set background color to Blue. - * Ps = 4 5 -> Set background color to Magenta. - * Ps = 4 6 -> Set background color to Cyan. - * Ps = 4 7 -> Set background color to White. - * Ps = 4 9 -> Set background color to default (original). - * - * If 16-color support is compiled, the following apply. Assume - * that xterm's resources are set so that the ISO color codes are - * the first 8 of a set of 16. Then the aixterm colors are the - * bright versions of the ISO colors: - * Ps = 9 0 -> Set foreground color to Black. - * Ps = 9 1 -> Set foreground color to Red. - * Ps = 9 2 -> Set foreground color to Green. - * Ps = 9 3 -> Set foreground color to Yellow. - * Ps = 9 4 -> Set foreground color to Blue. - * Ps = 9 5 -> Set foreground color to Magenta. - * Ps = 9 6 -> Set foreground color to Cyan. - * Ps = 9 7 -> Set foreground color to White. - * Ps = 1 0 0 -> Set background color to Black. - * Ps = 1 0 1 -> Set background color to Red. - * Ps = 1 0 2 -> Set background color to Green. - * Ps = 1 0 3 -> Set background color to Yellow. - * Ps = 1 0 4 -> Set background color to Blue. - * Ps = 1 0 5 -> Set background color to Magenta. - * Ps = 1 0 6 -> Set background color to Cyan. - * Ps = 1 0 7 -> Set background color to White. - * - * If xterm is compiled with the 16-color support disabled, it - * supports the following, from rxvt: - * Ps = 1 0 0 -> Set foreground and background color to - * default. - * - * If 88- or 256-color support is compiled, the following apply. - * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second - * Ps. - * Ps = 4 8 ; 5 ; Ps -> Set background color to the second - * Ps. - */ -Terminal.prototype.charAttributes = function (params) { - // Optimize a single SGR0. - if (params.length === 1 && params[0] === 0) { - this.curAttr = this.defAttr; - return; - } - var l = params.length, i = 0, flags = this.curAttr >> 18, fg = (this.curAttr >> 9) & 0x1ff, bg = this.curAttr & 0x1ff, p; - for (; i < l; i++) { - p = params[i]; - if (p >= 30 && p <= 37) { - // fg color 8 - fg = p - 30; - } - else if (p >= 40 && p <= 47) { - // bg color 8 - bg = p - 40; - } - else if (p >= 90 && p <= 97) { - // fg color 16 - p += 8; - fg = p - 90; - } - else if (p >= 100 && p <= 107) { - // bg color 16 - p += 8; - bg = p - 100; - } - else if (p === 0) { - // default - flags = this.defAttr >> 18; - fg = (this.defAttr >> 9) & 0x1ff; - bg = this.defAttr & 0x1ff; - } - else if (p === 1) { - // bold text - flags |= 1; - } - else if (p === 4) { - // underlined text - flags |= 2; - } - else if (p === 5) { - // blink - flags |= 4; - } - else if (p === 7) { - // inverse and positive - // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m' - flags |= 8; - } - else if (p === 8) { - // invisible - flags |= 16; - } - else if (p === 22) { - // not bold - flags &= ~1; - } - else if (p === 24) { - // not underlined - flags &= ~2; - } - else if (p === 25) { - // not blink - flags &= ~4; - } - else if (p === 27) { - // not inverse - flags &= ~8; - } - else if (p === 28) { - // not invisible - flags &= ~16; - } - else if (p === 39) { - // reset fg - fg = (this.defAttr >> 9) & 0x1ff; - } - else if (p === 49) { - // reset bg - bg = this.defAttr & 0x1ff; - } - else if (p === 38) { - // fg color 256 - if (params[i + 1] === 2) { - i += 2; - fg = matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); - if (fg === -1) - fg = 0x1ff; - i += 2; - } - else if (params[i + 1] === 5) { - i += 2; - p = params[i] & 0xff; - fg = p; - } - } - else if (p === 48) { - // bg color 256 - if (params[i + 1] === 2) { - i += 2; - bg = matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); - if (bg === -1) - bg = 0x1ff; - i += 2; - } - else if (params[i + 1] === 5) { - i += 2; - p = params[i] & 0xff; - bg = p; - } - } - else if (p === 100) { - // reset fg/bg - fg = (this.defAttr >> 9) & 0x1ff; - bg = this.defAttr & 0x1ff; - } - else { - this.error('Unknown SGR attribute: %d.', p); - } - } - this.curAttr = (flags << 18) | (fg << 9) | bg; -}; -/** - * CSI Ps n Device Status Report (DSR). - * Ps = 5 -> Status Report. Result (``OK'') is - * CSI 0 n - * Ps = 6 -> Report Cursor Position (CPR) [row;column]. - * Result is - * CSI r ; c R - * CSI ? Ps n - * Device Status Report (DSR, DEC-specific). - * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI - * ? r ; c R (assumes page is zero). - * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready). - * or CSI ? 1 1 n (not ready). - * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked) - * or CSI ? 2 1 n (locked). - * Ps = 2 6 -> Report Keyboard status as - * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American). - * The last two parameters apply to VT400 & up, and denote key- - * board ready and LK01 respectively. - * Ps = 5 3 -> Report Locator status as - * CSI ? 5 3 n Locator available, if compiled-in, or - * CSI ? 5 0 n No Locator, if not. - */ -Terminal.prototype.deviceStatus = function (params) { - if (!this.prefix) { - switch (params[0]) { - case 5: - // status report - this.send('\x1b[0n'); - break; - case 6: - // cursor position - this.send('\x1b[' - + (this.y + 1) - + ';' - + (this.x + 1) - + 'R'); - break; - } - } - else if (this.prefix === '?') { - // modern xterm doesnt seem to - // respond to any of these except ?6, 6, and 5 - switch (params[0]) { - case 6: - // cursor position - this.send('\x1b[?' - + (this.y + 1) - + ';' - + (this.x + 1) - + 'R'); - break; - case 15: - // no printer - // this.send('\x1b[?11n'); - break; - case 25: - // dont support user defined keys - // this.send('\x1b[?21n'); - break; - case 26: - // north american keyboard - // this.send('\x1b[?27;1;0;0n'); - break; - case 53: - // no dec locator/mouse - // this.send('\x1b[?50n'); - break; - } - } -}; -/** - * Additions - */ -/** - * CSI Ps @ - * Insert Ps (Blank) Character(s) (default = 1) (ICH). - */ -Terminal.prototype.insertChars = function (params) { - var param, row, j, ch; - param = params[0]; - if (param < 1) - param = 1; - row = this.y + this.ybase; - j = this.x; - ch = [this.eraseAttr(), ' ', 1]; // xterm - while (param-- && j < this.cols) { - this.lines[row].splice(j++, 0, ch); - this.lines[row].pop(); - } -}; -/** - * CSI Ps E - * Cursor Next Line Ps Times (default = 1) (CNL). - * same as CSI Ps B ? - */ -Terminal.prototype.cursorNextLine = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.y += param; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } - this.x = 0; -}; -/** - * CSI Ps F - * Cursor Preceding Line Ps Times (default = 1) (CNL). - * reuse CSI Ps A ? - */ -Terminal.prototype.cursorPrecedingLine = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.y -= param; - if (this.y < 0) - this.y = 0; - this.x = 0; -}; -/** - * CSI Ps G - * Cursor Character Absolute [column] (default = [row,1]) (CHA). - */ -Terminal.prototype.cursorCharAbsolute = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.x = param - 1; -}; -/** - * CSI Ps L - * Insert Ps Line(s) (default = 1) (IL). - */ -Terminal.prototype.insertLines = function (params) { - var param, row, j; - param = params[0]; - if (param < 1) - param = 1; - row = this.y + this.ybase; - j = this.rows - 1 - this.scrollBottom; - j = this.rows - 1 + this.ybase - j + 1; - while (param--) { - // test: echo -e '\e[44m\e[1L\e[0m' - // blankLine(true) - xterm/linux behavior - this.lines.splice(row, 0, this.blankLine(true)); - this.lines.splice(j, 1); - } - // this.maxRange(); - this.updateRange(this.y); - this.updateRange(this.scrollBottom); -}; -/** - * CSI Ps M - * Delete Ps Line(s) (default = 1) (DL). - */ -Terminal.prototype.deleteLines = function (params) { - var param, row, j; - param = params[0]; - if (param < 1) - param = 1; - row = this.y + this.ybase; - j = this.rows - 1 - this.scrollBottom; - j = this.rows - 1 + this.ybase - j; - while (param--) { - // test: echo -e '\e[44m\e[1M\e[0m' - // blankLine(true) - xterm/linux behavior - this.lines.splice(j + 1, 0, this.blankLine(true)); - this.lines.splice(row, 1); - } - // this.maxRange(); - this.updateRange(this.y); - this.updateRange(this.scrollBottom); -}; -/** - * CSI Ps P - * Delete Ps Character(s) (default = 1) (DCH). - */ -Terminal.prototype.deleteChars = function (params) { - var param, row, ch; - param = params[0]; - if (param < 1) - param = 1; - row = this.y + this.ybase; - ch = [this.eraseAttr(), ' ', 1]; // xterm - while (param--) { - this.lines[row].splice(this.x, 1); - this.lines[row].push(ch); - } -}; -/** - * CSI Ps X - * Erase Ps Character(s) (default = 1) (ECH). - */ -Terminal.prototype.eraseChars = function (params) { - var param, row, j, ch; - param = params[0]; - if (param < 1) - param = 1; - row = this.y + this.ybase; - j = this.x; - ch = [this.eraseAttr(), ' ', 1]; // xterm - while (param-- && j < this.cols) { - this.lines[row][j++] = ch; - } -}; -/** - * CSI Pm ` Character Position Absolute - * [column] (default = [row,1]) (HPA). - */ -Terminal.prototype.charPosAbsolute = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.x = param - 1; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; -/** - * 141 61 a * HPR - - * Horizontal Position Relative - * reuse CSI Ps C ? - */ -Terminal.prototype.HPositionRelative = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.x += param; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; -/** - * CSI Ps c Send Device Attributes (Primary DA). - * Ps = 0 or omitted -> request attributes from terminal. The - * response depends on the decTerminalID resource setting. - * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'') - * -> CSI ? 1 ; 0 c (``VT101 with No Options'') - * -> CSI ? 6 c (``VT102'') - * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'') - * The VT100-style response parameters do not mean anything by - * themselves. VT220 parameters do, telling the host what fea- - * tures the terminal supports: - * Ps = 1 -> 132-columns. - * Ps = 2 -> Printer. - * Ps = 6 -> Selective erase. - * Ps = 8 -> User-defined keys. - * Ps = 9 -> National replacement character sets. - * Ps = 1 5 -> Technical characters. - * Ps = 2 2 -> ANSI color, e.g., VT525. - * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode). - * CSI > Ps c - * Send Device Attributes (Secondary DA). - * Ps = 0 or omitted -> request the terminal's identification - * code. The response depends on the decTerminalID resource set- - * ting. It should apply only to VT220 and up, but xterm extends - * this to VT100. - * -> CSI > Pp ; Pv ; Pc c - * where Pp denotes the terminal type - * Pp = 0 -> ``VT100''. - * Pp = 1 -> ``VT220''. - * and Pv is the firmware version (for xterm, this was originally - * the XFree86 patch number, starting with 95). In a DEC termi- - * nal, Pc indicates the ROM cartridge registration number and is - * always zero. - * More information: - * xterm/charproc.c - line 2012, for more information. - * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?) - */ -Terminal.prototype.sendDeviceAttributes = function (params) { - if (params[0] > 0) - return; - if (!this.prefix) { - if (this.is('xterm') - || this.is('rxvt-unicode') - || this.is('screen')) { - this.send('\x1b[?1;2c'); - } - else if (this.is('linux')) { - this.send('\x1b[?6c'); - } - } - else if (this.prefix === '>') { - // xterm and urxvt - // seem to spit this - // out around ~370 times (?). - if (this.is('xterm')) { - this.send('\x1b[>0;276;0c'); - } - else if (this.is('rxvt-unicode')) { - this.send('\x1b[>85;95;0c'); - } - else if (this.is('linux')) { - // not supported by linux console. - // linux console echoes parameters. - this.send(params[0] + 'c'); - } - else if (this.is('screen')) { - this.send('\x1b[>83;40003;0c'); - } - } -}; -/** - * CSI Pm d - * Line Position Absolute [row] (default = [1,column]) (VPA). - */ -Terminal.prototype.linePosAbsolute = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.y = param - 1; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } -}; -/** - * 145 65 e * VPR - Vertical Position Relative - * reuse CSI Ps B ? - */ -Terminal.prototype.VPositionRelative = function (params) { - var param = params[0]; - if (param < 1) - param = 1; - this.y += param; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } -}; -/** - * CSI Ps ; Ps f - * Horizontal and Vertical Position [row;column] (default = - * [1,1]) (HVP). - */ -Terminal.prototype.HVPosition = function (params) { - if (params[0] < 1) - params[0] = 1; - if (params[1] < 1) - params[1] = 1; - this.y = params[0] - 1; - if (this.y >= this.rows) { - this.y = this.rows - 1; - } - this.x = params[1] - 1; - if (this.x >= this.cols) { - this.x = this.cols - 1; - } -}; -/** - * CSI Pm h Set Mode (SM). - * Ps = 2 -> Keyboard Action Mode (AM). - * Ps = 4 -> Insert Mode (IRM). - * Ps = 1 2 -> Send/receive (SRM). - * Ps = 2 0 -> Automatic Newline (LNM). - * CSI ? Pm h - * DEC Private Mode Set (DECSET). - * Ps = 1 -> Application Cursor Keys (DECCKM). - * Ps = 2 -> Designate USASCII for character sets G0-G3 - * (DECANM), and set VT100 mode. - * Ps = 3 -> 132 Column Mode (DECCOLM). - * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM). - * Ps = 5 -> Reverse Video (DECSCNM). - * Ps = 6 -> Origin Mode (DECOM). - * Ps = 7 -> Wraparound Mode (DECAWM). - * Ps = 8 -> Auto-repeat Keys (DECARM). - * Ps = 9 -> Send Mouse X & Y on button press. See the sec- - * tion Mouse Tracking. - * Ps = 1 0 -> Show toolbar (rxvt). - * Ps = 1 2 -> Start Blinking Cursor (att610). - * Ps = 1 8 -> Print form feed (DECPFF). - * Ps = 1 9 -> Set print extent to full screen (DECPEX). - * Ps = 2 5 -> Show Cursor (DECTCEM). - * Ps = 3 0 -> Show scrollbar (rxvt). - * Ps = 3 5 -> Enable font-shifting functions (rxvt). - * Ps = 3 8 -> Enter Tektronix Mode (DECTEK). - * Ps = 4 0 -> Allow 80 -> 132 Mode. - * Ps = 4 1 -> more(1) fix (see curses resource). - * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN- - * RCM). - * Ps = 4 4 -> Turn On Margin Bell. - * Ps = 4 5 -> Reverse-wraparound Mode. - * Ps = 4 6 -> Start Logging. This is normally disabled by a - * compile-time option. - * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis- - * abled by the titeInhibit resource). - * Ps = 6 6 -> Application keypad (DECNKM). - * Ps = 6 7 -> Backarrow key sends backspace (DECBKM). - * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and - * release. See the section Mouse Tracking. - * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking. - * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking. - * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking. - * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events. - * Ps = 1 0 0 5 -> Enable Extended Mouse Mode. - * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt). - * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt). - * Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit. - * (enables the eightBitInput resource). - * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num- - * Lock keys. (This enables the numLock resource). - * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This - * enables the metaSendsEscape resource). - * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete - * key. - * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This - * enables the altSendsEscape resource). - * Ps = 1 0 4 0 -> Keep selection even if not highlighted. - * (This enables the keepSelection resource). - * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables - * the selectToClipboard resource). - * Ps = 1 0 4 2 -> Enable Urgency window manager hint when - * Control-G is received. (This enables the bellIsUrgent - * resource). - * Ps = 1 0 4 3 -> Enable raising of the window when Control-G - * is received. (enables the popOnBell resource). - * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be - * disabled by the titeInhibit resource). - * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis- - * abled by the titeInhibit resource). - * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate - * Screen Buffer, clearing it first. (This may be disabled by - * the titeInhibit resource). This combines the effects of the 1 - * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based - * applications rather than the 4 7 mode. - * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode. - * Ps = 1 0 5 1 -> Set Sun function-key mode. - * Ps = 1 0 5 2 -> Set HP function-key mode. - * Ps = 1 0 5 3 -> Set SCO function-key mode. - * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6). - * Ps = 1 0 6 1 -> Set VT220 keyboard emulation. - * Ps = 2 0 0 4 -> Set bracketed paste mode. - * Modes: - * http: *vt100.net/docs/vt220-rm/chapter4.html - */ -Terminal.prototype.setMode = function (params) { - if (typeof params === 'object') { - var l = params.length, i = 0; - for (; i < l; i++) { - this.setMode(params[i]); - } - return; - } - if (!this.prefix) { - switch (params) { - case 4: - this.insertMode = true; - break; - case 20: - //this.convertEol = true; - break; - } - } - else if (this.prefix === '?') { - switch (params) { - case 1: - this.applicationCursor = true; - break; - case 2: - this.setgCharset(0, Terminal.charsets.US); - this.setgCharset(1, Terminal.charsets.US); - this.setgCharset(2, Terminal.charsets.US); - this.setgCharset(3, Terminal.charsets.US); - // set VT100 mode here - break; - case 3: - this.savedCols = this.cols; - this.resize(132, this.rows); - break; - case 6: - this.originMode = true; - break; - case 7: - this.wraparoundMode = true; - break; - case 12: - // this.cursorBlink = true; - break; - case 66: - this.log('Serial port requested application keypad.'); - this.applicationKeypad = true; - this.viewport.syncScrollArea(); - break; - case 9: // X10 Mouse - // no release, no motion, no wheel, no modifiers. - case 1000: // vt200 mouse - // no motion. - // no modifiers, except control on the wheel. - case 1002: // button event mouse - case 1003: - // any event - sends motion events, - // even if there is no button held down. - this.x10Mouse = params === 9; - this.vt200Mouse = params === 1000; - this.normalMouse = params > 1000; - this.mouseEvents = true; - this.element.style.cursor = 'default'; - this.log('Binding to mouse events.'); - break; - case 1004: - // focusin: ^[[I - // focusout: ^[[O - this.sendFocus = true; - break; - case 1005: - this.utfMouse = true; - // for wide terminals - // simply encodes large values as utf8 characters - break; - case 1006: - this.sgrMouse = true; - // for wide terminals - // does not add 32 to fields - // press: ^[[ Keyboard Action Mode (AM). - * Ps = 4 -> Replace Mode (IRM). - * Ps = 1 2 -> Send/receive (SRM). - * Ps = 2 0 -> Normal Linefeed (LNM). - * CSI ? Pm l - * DEC Private Mode Reset (DECRST). - * Ps = 1 -> Normal Cursor Keys (DECCKM). - * Ps = 2 -> Designate VT52 mode (DECANM). - * Ps = 3 -> 80 Column Mode (DECCOLM). - * Ps = 4 -> Jump (Fast) Scroll (DECSCLM). - * Ps = 5 -> Normal Video (DECSCNM). - * Ps = 6 -> Normal Cursor Mode (DECOM). - * Ps = 7 -> No Wraparound Mode (DECAWM). - * Ps = 8 -> No Auto-repeat Keys (DECARM). - * Ps = 9 -> Don't send Mouse X & Y on button press. - * Ps = 1 0 -> Hide toolbar (rxvt). - * Ps = 1 2 -> Stop Blinking Cursor (att610). - * Ps = 1 8 -> Don't print form feed (DECPFF). - * Ps = 1 9 -> Limit print to scrolling region (DECPEX). - * Ps = 2 5 -> Hide Cursor (DECTCEM). - * Ps = 3 0 -> Don't show scrollbar (rxvt). - * Ps = 3 5 -> Disable font-shifting functions (rxvt). - * Ps = 4 0 -> Disallow 80 -> 132 Mode. - * Ps = 4 1 -> No more(1) fix (see curses resource). - * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC- - * NRCM). - * Ps = 4 4 -> Turn Off Margin Bell. - * Ps = 4 5 -> No Reverse-wraparound Mode. - * Ps = 4 6 -> Stop Logging. (This is normally disabled by a - * compile-time option). - * Ps = 4 7 -> Use Normal Screen Buffer. - * Ps = 6 6 -> Numeric keypad (DECNKM). - * Ps = 6 7 -> Backarrow key sends delete (DECBKM). - * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and - * release. See the section Mouse Tracking. - * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking. - * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking. - * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking. - * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events. - * Ps = 1 0 0 5 -> Disable Extended Mouse Mode. - * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output - * (rxvt). - * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt). - * Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables - * the eightBitInput resource). - * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num- - * Lock keys. (This disables the numLock resource). - * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key. - * (This disables the metaSendsEscape resource). - * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad - * Delete key. - * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key. - * (This disables the altSendsEscape resource). - * Ps = 1 0 4 0 -> Do not keep selection when not highlighted. - * (This disables the keepSelection resource). - * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables - * the selectToClipboard resource). - * Ps = 1 0 4 2 -> Disable Urgency window manager hint when - * Control-G is received. (This disables the bellIsUrgent - * resource). - * Ps = 1 0 4 3 -> Disable raising of the window when Control- - * G is received. (This disables the popOnBell resource). - * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen - * first if in the Alternate Screen. (This may be disabled by - * the titeInhibit resource). - * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be - * disabled by the titeInhibit resource). - * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor - * as in DECRC. (This may be disabled by the titeInhibit - * resource). This combines the effects of the 1 0 4 7 and 1 0 - * 4 8 modes. Use this with terminfo-based applications rather - * than the 4 7 mode. - * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode. - * Ps = 1 0 5 1 -> Reset Sun function-key mode. - * Ps = 1 0 5 2 -> Reset HP function-key mode. - * Ps = 1 0 5 3 -> Reset SCO function-key mode. - * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6). - * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style. - * Ps = 2 0 0 4 -> Reset bracketed paste mode. - */ -Terminal.prototype.resetMode = function (params) { - if (typeof params === 'object') { - var l = params.length, i = 0; - for (; i < l; i++) { - this.resetMode(params[i]); - } - return; - } - if (!this.prefix) { - switch (params) { - case 4: - this.insertMode = false; - break; - case 20: - //this.convertEol = false; - break; - } - } - else if (this.prefix === '?') { - switch (params) { - case 1: - this.applicationCursor = false; - break; - case 3: - if (this.cols === 132 && this.savedCols) { - this.resize(this.savedCols, this.rows); - } - delete this.savedCols; - break; - case 6: - this.originMode = false; - break; - case 7: - this.wraparoundMode = false; - break; - case 12: - // this.cursorBlink = false; - break; - case 66: - this.log('Switching back to normal keypad.'); - this.applicationKeypad = false; - this.viewport.syncScrollArea(); - break; - case 9: // X10 Mouse - case 1000: // vt200 mouse - case 1002: // button event mouse - case 1003: - this.x10Mouse = false; - this.vt200Mouse = false; - this.normalMouse = false; - this.mouseEvents = false; - this.element.style.cursor = ''; - break; - case 1004: - this.sendFocus = false; - break; - case 1005: - this.utfMouse = false; - break; - case 1006: - this.sgrMouse = false; - break; - case 1015: - this.urxvtMouse = false; - break; - case 25: - this.cursorHidden = true; - break; - case 1049: - ; // FALL-THROUGH - case 47: // normal screen buffer - case 1047: - if (this.normal) { - this.lines = this.normal.lines; - this.ybase = this.normal.ybase; - this.ydisp = this.normal.ydisp; - this.x = this.normal.x; - this.y = this.normal.y; - this.scrollTop = this.normal.scrollTop; - this.scrollBottom = this.normal.scrollBottom; - this.tabs = this.normal.tabs; - this.normal = null; - // if (params === 1049) { - // this.x = this.savedX; - // this.y = this.savedY; - // } - this.refresh(0, this.rows - 1); - this.showCursor(); - } - break; - } - } -}; -/** - * CSI Ps ; Ps r - * Set Scrolling Region [top;bottom] (default = full size of win- - * dow) (DECSTBM). - * CSI ? Pm r - */ -Terminal.prototype.setScrollRegion = function (params) { - if (this.prefix) - return; - this.scrollTop = (params[0] || 1) - 1; - this.scrollBottom = (params[1] || this.rows) - 1; - this.x = 0; - this.y = 0; -}; -/** - * CSI s - * Save cursor (ANSI.SYS). - */ -Terminal.prototype.saveCursor = function (params) { - this.savedX = this.x; - this.savedY = this.y; -}; -/** - * CSI u - * Restore cursor (ANSI.SYS). - */ -Terminal.prototype.restoreCursor = function (params) { - this.x = this.savedX || 0; - this.y = this.savedY || 0; -}; -/** - * Lesser Used - */ -/** - * CSI Ps I - * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). - */ -Terminal.prototype.cursorForwardTab = function (params) { - var param = params[0] || 1; - while (param--) { - this.x = this.nextStop(); - } -}; -/** - * CSI Ps S Scroll up Ps lines (default = 1) (SU). - */ -Terminal.prototype.scrollUp = function (params) { - var param = params[0] || 1; - while (param--) { - this.lines.splice(this.ybase + this.scrollTop, 1); - this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine()); - } - // this.maxRange(); - this.updateRange(this.scrollTop); - this.updateRange(this.scrollBottom); -}; -/** - * CSI Ps T Scroll down Ps lines (default = 1) (SD). - */ -Terminal.prototype.scrollDown = function (params) { - var param = params[0] || 1; - while (param--) { - this.lines.splice(this.ybase + this.scrollBottom, 1); - this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine()); - } - // this.maxRange(); - this.updateRange(this.scrollTop); - this.updateRange(this.scrollBottom); -}; -/** - * CSI Ps ; Ps ; Ps ; Ps ; Ps T - * Initiate highlight mouse tracking. Parameters are - * [func;startx;starty;firstrow;lastrow]. See the section Mouse - * Tracking. - */ -Terminal.prototype.initMouseTracking = function (params) { - // Relevant: DECSET 1001 -}; -/** - * CSI > Ps; Ps T - * Reset one or more features of the title modes to the default - * value. Normally, "reset" disables the feature. It is possi- - * ble to disable the ability to reset features by compiling a - * different default for the title modes into xterm. - * Ps = 0 -> Do not set window/icon labels using hexadecimal. - * Ps = 1 -> Do not query window/icon labels using hexadeci- - * mal. - * Ps = 2 -> Do not set window/icon labels using UTF-8. - * Ps = 3 -> Do not query window/icon labels using UTF-8. - * (See discussion of "Title Modes"). - */ -Terminal.prototype.resetTitleModes = function (params) { - ; -}; -/** - * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). - */ -Terminal.prototype.cursorBackwardTab = function (params) { - var param = params[0] || 1; - while (param--) { - this.x = this.prevStop(); - } -}; -/** - * CSI Ps b Repeat the preceding graphic character Ps times (REP). - */ -Terminal.prototype.repeatPrecedingCharacter = function (params) { - var param = params[0] || 1, line = this.lines[this.ybase + this.y], ch = line[this.x - 1] || [this.defAttr, ' ', 1]; - while (param--) - line[this.x++] = ch; -}; -/** - * CSI Ps g Tab Clear (TBC). - * Ps = 0 -> Clear Current Column (default). - * Ps = 3 -> Clear All. - * Potentially: - * Ps = 2 -> Clear Stops on Line. - * http://vt100.net/annarbor/aaa-ug/section6.html - */ -Terminal.prototype.tabClear = function (params) { - var param = params[0]; - if (param <= 0) { - delete this.tabs[this.x]; - } - else if (param === 3) { - this.tabs = {}; - } -}; -/** - * CSI Pm i Media Copy (MC). - * Ps = 0 -> Print screen (default). - * Ps = 4 -> Turn off printer controller mode. - * Ps = 5 -> Turn on printer controller mode. - * CSI ? Pm i - * Media Copy (MC, DEC-specific). - * Ps = 1 -> Print line containing cursor. - * Ps = 4 -> Turn off autoprint mode. - * Ps = 5 -> Turn on autoprint mode. - * Ps = 1 0 -> Print composed display, ignores DECPEX. - * Ps = 1 1 -> Print all pages. - */ -Terminal.prototype.mediaCopy = function (params) { - ; -}; -/** - * CSI > Ps; Ps m - * Set or reset resource-values used by xterm to decide whether - * to construct escape sequences holding information about the - * modifiers pressed with a given key. The first parameter iden- - * tifies the resource to set/reset. The second parameter is the - * value to assign to the resource. If the second parameter is - * omitted, the resource is reset to its initial value. - * Ps = 1 -> modifyCursorKeys. - * Ps = 2 -> modifyFunctionKeys. - * Ps = 4 -> modifyOtherKeys. - * If no parameters are given, all resources are reset to their - * initial values. - */ -Terminal.prototype.setResources = function (params) { - ; -}; -/** - * CSI > Ps n - * Disable modifiers which may be enabled via the CSI > Ps; Ps m - * sequence. This corresponds to a resource value of "-1", which - * cannot be set with the other sequence. The parameter identi- - * fies the resource to be disabled: - * Ps = 1 -> modifyCursorKeys. - * Ps = 2 -> modifyFunctionKeys. - * Ps = 4 -> modifyOtherKeys. - * If the parameter is omitted, modifyFunctionKeys is disabled. - * When modifyFunctionKeys is disabled, xterm uses the modifier - * keys to make an extended sequence of functions rather than - * adding a parameter to each function key to denote the modi- - * fiers. - */ -Terminal.prototype.disableModifiers = function (params) { - ; -}; -/** - * CSI > Ps p - * Set resource value pointerMode. This is used by xterm to - * decide whether to hide the pointer cursor as the user types. - * Valid values for the parameter: - * Ps = 0 -> never hide the pointer. - * Ps = 1 -> hide if the mouse tracking mode is not enabled. - * Ps = 2 -> always hide the pointer. If no parameter is - * given, xterm uses the default, which is 1 . - */ -Terminal.prototype.setPointerMode = function (params) { - ; -}; -/** - * CSI ! p Soft terminal reset (DECSTR). - * http://vt100.net/docs/vt220-rm/table4-10.html - */ -Terminal.prototype.softReset = function (params) { - this.cursorHidden = false; - this.insertMode = false; - this.originMode = false; - this.wraparoundMode = false; // autowrap - this.applicationKeypad = false; // ? - this.viewport.syncScrollArea(); - this.applicationCursor = false; - this.scrollTop = 0; - this.scrollBottom = this.rows - 1; - this.curAttr = this.defAttr; - this.x = this.y = 0; // ? - this.charset = null; - this.glevel = 0; // ?? - this.charsets = [null]; // ?? -}; -/** - * CSI Ps$ p - * Request ANSI mode (DECRQM). For VT300 and up, reply is - * CSI Ps; Pm$ y - * where Ps is the mode number as in RM, and Pm is the mode - * value: - * 0 - not recognized - * 1 - set - * 2 - reset - * 3 - permanently set - * 4 - permanently reset - */ -Terminal.prototype.requestAnsiMode = function (params) { - ; -}; -/** - * CSI ? Ps$ p - * Request DEC private mode (DECRQM). For VT300 and up, reply is - * CSI ? Ps; Pm$ p - * where Ps is the mode number as in DECSET, Pm is the mode value - * as in the ANSI DECRQM. - */ -Terminal.prototype.requestPrivateMode = function (params) { - ; -}; -/** - * CSI Ps ; Ps " p - * Set conformance level (DECSCL). Valid values for the first - * parameter: - * Ps = 6 1 -> VT100. - * Ps = 6 2 -> VT200. - * Ps = 6 3 -> VT300. - * Valid values for the second parameter: - * Ps = 0 -> 8-bit controls. - * Ps = 1 -> 7-bit controls (always set for VT100). - * Ps = 2 -> 8-bit controls. - */ -Terminal.prototype.setConformanceLevel = function (params) { - ; -}; -/** - * CSI Ps q Load LEDs (DECLL). - * Ps = 0 -> Clear all LEDS (default). - * Ps = 1 -> Light Num Lock. - * Ps = 2 -> Light Caps Lock. - * Ps = 3 -> Light Scroll Lock. - * Ps = 2 1 -> Extinguish Num Lock. - * Ps = 2 2 -> Extinguish Caps Lock. - * Ps = 2 3 -> Extinguish Scroll Lock. - */ -Terminal.prototype.loadLEDs = function (params) { - ; -}; -/** - * CSI Ps SP q - * Set cursor style (DECSCUSR, VT520). - * Ps = 0 -> blinking block. - * Ps = 1 -> blinking block (default). - * Ps = 2 -> steady block. - * Ps = 3 -> blinking underline. - * Ps = 4 -> steady underline. - */ -Terminal.prototype.setCursorStyle = function (params) { - ; -}; -/** - * CSI Ps " q - * Select character protection attribute (DECSCA). Valid values - * for the parameter: - * Ps = 0 -> DECSED and DECSEL can erase (default). - * Ps = 1 -> DECSED and DECSEL cannot erase. - * Ps = 2 -> DECSED and DECSEL can erase. - */ -Terminal.prototype.setCharProtectionAttr = function (params) { - ; -}; -/** - * CSI ? Pm r - * Restore DEC Private Mode Values. The value of Ps previously - * saved is restored. Ps values are the same as for DECSET. - */ -Terminal.prototype.restorePrivateValues = function (params) { - ; -}; -/** - * CSI Pt; Pl; Pb; Pr; Ps$ r - * Change Attributes in Rectangular Area (DECCARA), VT400 and up. - * Pt; Pl; Pb; Pr denotes the rectangle. - * Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.setAttrInRectangle = function (params) { - var t = params[0], l = params[1], b = params[2], r = params[3], attr = params[4]; - var line, i; - for (; t < b + 1; t++) { - line = this.lines[this.ybase + t]; - for (i = l; i < r; i++) { - line[i] = [attr, line[i][1]]; - } - } - // this.maxRange(); - this.updateRange(params[0]); - this.updateRange(params[2]); -}; -/** - * CSI Pc; Pt; Pl; Pb; Pr$ x - * Fill Rectangular Area (DECFRA), VT420 and up. - * Pc is the character to use. - * Pt; Pl; Pb; Pr denotes the rectangle. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.fillRectangle = function (params) { - var ch = params[0], t = params[1], l = params[2], b = params[3], r = params[4]; - var line, i; - for (; t < b + 1; t++) { - line = this.lines[this.ybase + t]; - for (i = l; i < r; i++) { - line[i] = [line[i][0], String.fromCharCode(ch)]; - } - } - // this.maxRange(); - this.updateRange(params[1]); - this.updateRange(params[3]); -}; -/** - * CSI Ps ; Pu ' z - * Enable Locator Reporting (DECELR). - * Valid values for the first parameter: - * Ps = 0 -> Locator disabled (default). - * Ps = 1 -> Locator enabled. - * Ps = 2 -> Locator enabled for one report, then disabled. - * The second parameter specifies the coordinate unit for locator - * reports. - * Valid values for the second parameter: - * Pu = 0 <- or omitted -> default to character cells. - * Pu = 1 <- device physical pixels. - * Pu = 2 <- character cells. - */ -Terminal.prototype.enableLocatorReporting = function (params) { - var val = params[0] > 0; - //this.mouseEvents = val; - //this.decLocator = val; -}; -/** - * CSI Pt; Pl; Pb; Pr$ z - * Erase Rectangular Area (DECERA), VT400 and up. - * Pt; Pl; Pb; Pr denotes the rectangle. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.eraseRectangle = function (params) { - var t = params[0], l = params[1], b = params[2], r = params[3]; - var line, i, ch; - ch = [this.eraseAttr(), ' ', 1]; // xterm? - for (; t < b + 1; t++) { - line = this.lines[this.ybase + t]; - for (i = l; i < r; i++) { - line[i] = ch; - } - } - // this.maxRange(); - this.updateRange(params[0]); - this.updateRange(params[2]); -}; -/** - * CSI P m SP } - * Insert P s Column(s) (default = 1) (DECIC), VT420 and up. - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.insertColumns = function () { - var param = params[0], l = this.ybase + this.rows, ch = [this.eraseAttr(), ' ', 1] // xterm? - , i; - while (param--) { - for (i = this.ybase; i < l; i++) { - this.lines[i].splice(this.x + 1, 0, ch); - this.lines[i].pop(); - } - } - this.maxRange(); -}; -/** - * CSI P m SP ~ - * Delete P s Column(s) (default = 1) (DECDC), VT420 and up - * NOTE: xterm doesn't enable this code by default. - */ -Terminal.prototype.deleteColumns = function () { - var param = params[0], l = this.ybase + this.rows, ch = [this.eraseAttr(), ' ', 1] // xterm? - , i; - while (param--) { - for (i = this.ybase; i < l; i++) { - this.lines[i].splice(this.x, 1); - this.lines[i].push(ch); - } - } - this.maxRange(); -}; -/** - * Character Sets - */ -Terminal.charsets = {}; -// DEC Special Character and Line Drawing Set. -// http://vt100.net/docs/vt102-ug/table5-13.html -// A lot of curses apps use this if they see TERM=xterm. -// testing: echo -e '\e(0a\e(B' -// The xterm output sometimes seems to conflict with the -// reference above. xterm seems in line with the reference -// when running vttest however. -// The table below now uses xterm's output from vttest. -Terminal.charsets.SCLD = { +exports.CHARSETS = {}; +exports.DEFAULT_CHARSET = exports.CHARSETS['B']; +exports.CHARSETS['0'] = { '`': '\u25c6', 'a': '\u2592', 'b': '\u0009', @@ -4919,131 +33,1179 @@ Terminal.charsets.SCLD = { '{': '\u03c0', '|': '\u2260', '}': '\u00a3', - '~': '\u00b7' // '·' + '~': '\u00b7' }; -Terminal.charsets.UK = null; // (A -Terminal.charsets.US = null; // (B (USASCII) -Terminal.charsets.Dutch = null; // (4 -Terminal.charsets.Finnish = null; // (C or (5 -Terminal.charsets.French = null; // (R -Terminal.charsets.FrenchCanadian = null; // (Q -Terminal.charsets.German = null; // (K -Terminal.charsets.Italian = null; // (Y -Terminal.charsets.NorwegianDanish = null; // (E or (6 -Terminal.charsets.Spanish = null; // (Z -Terminal.charsets.Swedish = null; // (H or (7 -Terminal.charsets.Swiss = null; // (= -Terminal.charsets.ISOLatin = null; // /A -/** - * Helpers - */ -function on(el, type, handler, capture) { - if (!Array.isArray(el)) { - el = [el]; - } - el.forEach(function (element) { - element.addEventListener(type, handler, capture || false); - }); -} -function off(el, type, handler, capture) { - el.removeEventListener(type, handler, capture || false); -} -function cancel(ev, force) { - if (!this.cancelEvents && !force) { - return; - } - ev.preventDefault(); - ev.stopPropagation(); - return false; -} -function inherits(child, parent) { - function f() { - this.constructor = child; - } - f.prototype = parent.prototype; - child.prototype = new f; -} -// if bold is broken, we can't -// use it in the terminal. -function isBoldBroken(document) { - var body = document.getElementsByTagName('body')[0]; - var el = document.createElement('span'); - el.innerHTML = 'hello world'; - body.appendChild(el); - var w1 = el.scrollWidth; - el.style.fontWeight = 'bold'; - var w2 = el.scrollWidth; - body.removeChild(el); - return w1 !== w2; -} -function indexOf(obj, el) { - var i = obj.length; - while (i--) { - if (obj[i] === el) - return i; - } - return -1; -} -function isThirdLevelShift(term, ev) { - var thirdLevelKey = (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || - (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); - if (ev.type == 'keypress') { - return thirdLevelKey; - } - // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events) - return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); -} -function matchColor(r1, g1, b1) { - var hash = (r1 << 16) | (g1 << 8) | b1; - if (matchColor._cache[hash] != null) { - return matchColor._cache[hash]; - } - var ldiff = Infinity, li = -1, i = 0, c, r2, g2, b2, diff; - for (; i < Terminal.vcolors.length; i++) { - c = Terminal.vcolors[i]; - r2 = c[0]; - g2 = c[1]; - b2 = c[2]; - diff = matchColor.distance(r1, g1, b1, r2, g2, b2); - if (diff === 0) { - li = i; - break; - } - if (diff < ldiff) { - ldiff = diff; - li = i; - } - } - return matchColor._cache[hash] = li; -} -matchColor._cache = {}; -// http://stackoverflow.com/questions/1633828 -matchColor.distance = function (r1, g1, b1, r2, g2, b2) { - return Math.pow(30 * (r1 - r2), 2) - + Math.pow(59 * (g1 - g2), 2) - + Math.pow(11 * (b1 - b2), 2); +exports.CHARSETS['A'] = { + '#': '£' }; -function each(obj, iter, con) { - if (obj.forEach) - return obj.forEach(iter, con); - for (var i = 0; i < obj.length; i++) { - iter.call(con, obj[i], i, obj); +exports.CHARSETS['B'] = null; +exports.CHARSETS['4'] = { + '#': '£', + '@': '¾', + '[': 'ij', + '\\': '½', + ']': '|', + '{': '¨', + '|': 'f', + '}': '¼', + '~': '´' +}; +exports.CHARSETS['C'] = + exports.CHARSETS['5'] = { + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['R'] = { + '#': '£', + '@': 'à', + '[': '°', + '\\': 'ç', + ']': '§', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': '¨' +}; +exports.CHARSETS['Q'] = { + '@': 'à', + '[': 'â', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '`': 'ô', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': 'û' +}; +exports.CHARSETS['K'] = { + '@': '§', + '[': 'Ä', + '\\': 'Ö', + ']': 'Ü', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'ß' +}; +exports.CHARSETS['Y'] = { + '#': '£', + '@': '§', + '[': '°', + '\\': 'ç', + ']': 'é', + '`': 'ù', + '{': 'à', + '|': 'ò', + '}': 'è', + '~': 'ì' +}; +exports.CHARSETS['E'] = + exports.CHARSETS['6'] = { + '@': 'Ä', + '[': 'Æ', + '\\': 'Ø', + ']': 'Å', + '^': 'Ü', + '`': 'ä', + '{': 'æ', + '|': 'ø', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['Z'] = { + '#': '£', + '@': '§', + '[': '¡', + '\\': 'Ñ', + ']': '¿', + '{': '°', + '|': 'ñ', + '}': 'ç' +}; +exports.CHARSETS['H'] = + exports.CHARSETS['7'] = { + '@': 'É', + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['='] = { + '#': 'ù', + '@': 'à', + '[': 'é', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '_': 'è', + '`': 'ô', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'û' +}; + +},{}],2:[function(require,module,exports){ +"use strict"; +var CompositionHelper = (function () { + function CompositionHelper(textarea, compositionView, terminal) { + this.textarea = textarea; + this.compositionView = compositionView; + this.terminal = terminal; + this.isComposing = false; + this.isSendingComposition = false; + this.compositionPosition = { start: null, end: null }; } -} -function keys(obj) { - if (Object.keys) - return Object.keys(obj); - var key, keys = []; - for (key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - keys.push(key); + CompositionHelper.prototype.compositionstart = function () { + this.isComposing = true; + this.compositionPosition.start = this.textarea.value.length; + this.compositionView.textContent = ''; + this.compositionView.classList.add('active'); + }; + CompositionHelper.prototype.compositionupdate = function (ev) { + var _this = this; + this.compositionView.textContent = ev.data; + this.updateCompositionElements(); + setTimeout(function () { + _this.compositionPosition.end = _this.textarea.value.length; + }, 0); + }; + CompositionHelper.prototype.compositionend = function () { + this.finalizeComposition(true); + }; + CompositionHelper.prototype.keydown = function (ev) { + if (this.isComposing || this.isSendingComposition) { + if (ev.keyCode === 229) { + return false; + } + else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { + return false; + } + else { + this.finalizeComposition(false); + } } + if (ev.keyCode === 229) { + this.handleAnyTextareaChanges(); + return false; + } + return true; + }; + CompositionHelper.prototype.finalizeComposition = function (waitForPropogation) { + var _this = this; + this.compositionView.classList.remove('active'); + this.isComposing = false; + this.clearTextareaPosition(); + if (!waitForPropogation) { + this.isSendingComposition = false; + var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end); + this.terminal.handler(input); + } + else { + var currentCompositionPosition_1 = { + start: this.compositionPosition.start, + end: this.compositionPosition.end, + }; + this.isSendingComposition = true; + setTimeout(function () { + if (_this.isSendingComposition) { + _this.isSendingComposition = false; + var input = void 0; + if (_this.isComposing) { + input = _this.textarea.value.substring(currentCompositionPosition_1.start, currentCompositionPosition_1.end); + } + else { + input = _this.textarea.value.substring(currentCompositionPosition_1.start); + } + _this.terminal.handler(input); + } + }, 0); + } + }; + CompositionHelper.prototype.handleAnyTextareaChanges = function () { + var _this = this; + var oldValue = this.textarea.value; + setTimeout(function () { + if (!_this.isComposing) { + var newValue = _this.textarea.value; + var diff = newValue.replace(oldValue, ''); + if (diff.length > 0) { + _this.terminal.handler(diff); + } + } + }, 0); + }; + CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) { + var _this = this; + if (!this.isComposing) { + return; + } + var cursor = this.terminal.element.querySelector('.terminal-cursor'); + if (cursor) { + var xtermRows = this.terminal.element.querySelector('.xterm-rows'); + var cursorTop = xtermRows.offsetTop + cursor.offsetTop; + this.compositionView.style.left = cursor.offsetLeft + 'px'; + this.compositionView.style.top = cursorTop + 'px'; + this.compositionView.style.height = cursor.offsetHeight + 'px'; + this.compositionView.style.lineHeight = cursor.offsetHeight + 'px'; + var compositionViewBounds = this.compositionView.getBoundingClientRect(); + this.textarea.style.left = cursor.offsetLeft + 'px'; + this.textarea.style.top = cursorTop + 'px'; + this.textarea.style.width = compositionViewBounds.width + 'px'; + this.textarea.style.height = compositionViewBounds.height + 'px'; + this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; + } + if (!dontRecurse) { + setTimeout(function () { return _this.updateCompositionElements(true); }, 0); + } + }; + ; + CompositionHelper.prototype.clearTextareaPosition = function () { + this.textarea.style.left = ''; + this.textarea.style.top = ''; + }; + ; + return CompositionHelper; +}()); +exports.CompositionHelper = CompositionHelper; + +},{}],3:[function(require,module,exports){ +"use strict"; +var C0; +(function (C0) { + C0.NUL = '\x00'; + C0.SOH = '\x01'; + C0.STX = '\x02'; + C0.ETX = '\x03'; + C0.EOT = '\x04'; + C0.ENQ = '\x05'; + C0.ACK = '\x06'; + C0.BEL = '\x07'; + C0.BS = '\x08'; + C0.HT = '\x09'; + C0.LF = '\x0a'; + C0.VT = '\x0b'; + C0.FF = '\x0c'; + C0.CR = '\x0d'; + C0.SO = '\x0e'; + C0.SI = '\x0f'; + C0.DLE = '\x10'; + C0.DC1 = '\x11'; + C0.DC2 = '\x12'; + C0.DC3 = '\x13'; + C0.DC4 = '\x14'; + C0.NAK = '\x15'; + C0.SYN = '\x16'; + C0.ETB = '\x17'; + C0.CAN = '\x18'; + C0.EM = '\x19'; + C0.SUB = '\x1a'; + C0.ESC = '\x1b'; + C0.FS = '\x1c'; + C0.GS = '\x1d'; + C0.RS = '\x1e'; + C0.US = '\x1f'; + C0.SP = '\x20'; + C0.DEL = '\x7f'; +})(C0 = exports.C0 || (exports.C0 = {})); +; + +},{}],4:[function(require,module,exports){ +"use strict"; +; +var EventEmitter = (function () { + function EventEmitter() { + this._events = this._events || {}; } - return keys; -} + EventEmitter.prototype.on = function (type, listener) { + this._events[type] = this._events[type] || []; + this._events[type].push(listener); + }; + EventEmitter.prototype.off = function (type, listener) { + if (!this._events[type]) { + return; + } + var obj = this._events[type]; + var i = obj.length; + while (i--) { + if (obj[i] === listener || obj[i].listener === listener) { + obj.splice(i, 1); + return; + } + } + }; + EventEmitter.prototype.removeAllListeners = function (type) { + if (this._events[type]) { + delete this._events[type]; + } + }; + EventEmitter.prototype.once = function (type, listener) { + function on() { + var args = Array.prototype.slice.call(arguments); + this.off(type, on); + return listener.apply(this, args); + } + on.listener = listener; + return this.on(type, on); + }; + EventEmitter.prototype.emit = function (type) { + if (!this._events[type]) { + return; + } + var args = Array.prototype.slice.call(arguments, 1); + var obj = this._events[type]; + for (var i = 0; i < obj.length; i++) { + obj[i].apply(this, args); + } + }; + EventEmitter.prototype.listeners = function (type) { + return this._events[type] || []; + }; + return EventEmitter; +}()); +exports.EventEmitter = EventEmitter; + +},{}],5:[function(require,module,exports){ +"use strict"; +var EscapeSequences_1 = require("./EscapeSequences"); +var Charsets_1 = require("./Charsets"); +var InputHandler = (function () { + function InputHandler(_terminal) { + this._terminal = _terminal; + } + InputHandler.prototype.addChar = function (char, code) { + if (char >= ' ') { + var ch_width = wcwidth(code); + if (this._terminal.charset && this._terminal.charset[char]) { + char = this._terminal.charset[char]; + } + var row = this._terminal.y + this._terminal.ybase; + if (!ch_width && this._terminal.x) { + if (this._terminal.lines.get(row)[this._terminal.x - 1]) { + if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) { + if (this._terminal.lines.get(row)[this._terminal.x - 2]) + this._terminal.lines.get(row)[this._terminal.x - 2][1] += char; + } + else { + this._terminal.lines.get(row)[this._terminal.x - 1][1] += char; + } + this._terminal.updateRange(this._terminal.y); + } + return; + } + if (this._terminal.x + ch_width - 1 >= this._terminal.cols) { + if (this._terminal.wraparoundMode) { + this._terminal.x = 0; + this._terminal.y++; + if (this._terminal.y > this._terminal.scrollBottom) { + this._terminal.y--; + this._terminal.scroll(); + } + } + else { + if (ch_width === 2) + return; + } + } + row = this._terminal.y + this._terminal.ybase; + if (this._terminal.insertMode) { + for (var moves = 0; moves < ch_width; ++moves) { + var removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop(); + if (removed[2] === 0 + && this._terminal.lines.get(row)[this._terminal.cols - 2] + && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2) + this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1]; + this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]); + } + } + this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width]; + this._terminal.x++; + this._terminal.updateRange(this._terminal.y); + if (ch_width === 2) { + this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0]; + this._terminal.x++; + } + } + }; + InputHandler.prototype.bell = function () { + var _this = this; + if (!this._terminal.visualBell) { + return; + } + this._terminal.element.style.borderColor = 'white'; + setTimeout(function () { return _this._terminal.element.style.borderColor = ''; }, 10); + if (this._terminal.popOnBell) { + this._terminal.focus(); + } + }; + InputHandler.prototype.lineFeed = function () { + if (this._terminal.convertEol) { + this._terminal.x = 0; + } + this._terminal.y++; + if (this._terminal.y > this._terminal.scrollBottom) { + this._terminal.y--; + this._terminal.scroll(); + } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } + }; + InputHandler.prototype.carriageReturn = function () { + this._terminal.x = 0; + }; + InputHandler.prototype.backspace = function () { + if (this._terminal.x > 0) { + this._terminal.x--; + } + }; + InputHandler.prototype.tab = function () { + this._terminal.x = this._terminal.nextStop(); + }; + InputHandler.prototype.shiftOut = function () { + this._terminal.setgLevel(1); + }; + InputHandler.prototype.shiftIn = function () { + this._terminal.setgLevel(0); + }; + InputHandler.prototype.insertChars = function (params) { + var param, row, j, ch; + param = params[0]; + if (param < 1) + param = 1; + row = this._terminal.y + this._terminal.ybase; + j = this._terminal.x; + ch = [this._terminal.eraseAttr(), ' ', 1]; + while (param-- && j < this._terminal.cols) { + this._terminal.lines.get(row).splice(j++, 0, ch); + this._terminal.lines.get(row).pop(); + } + }; + InputHandler.prototype.cursorUp = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y -= param; + if (this._terminal.y < 0) { + this._terminal.y = 0; + } + }; + InputHandler.prototype.cursorDown = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y += param; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } + }; + InputHandler.prototype.cursorForward = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x += param; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.cursorBackward = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } + this._terminal.x -= param; + if (this._terminal.x < 0) { + this._terminal.x = 0; + } + }; + InputHandler.prototype.cursorNextLine = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y += param; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + this._terminal.x = 0; + }; + ; + InputHandler.prototype.cursorPrecedingLine = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y -= param; + if (this._terminal.y < 0) { + this._terminal.y = 0; + } + this._terminal.x = 0; + }; + ; + InputHandler.prototype.cursorCharAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x = param - 1; + }; + InputHandler.prototype.cursorPosition = function (params) { + var row, col; + row = params[0] - 1; + if (params.length >= 2) { + col = params[1] - 1; + } + else { + col = 0; + } + if (row < 0) { + row = 0; + } + else if (row >= this._terminal.rows) { + row = this._terminal.rows - 1; + } + if (col < 0) { + col = 0; + } + else if (col >= this._terminal.cols) { + col = this._terminal.cols - 1; + } + this._terminal.x = col; + this._terminal.y = row; + }; + InputHandler.prototype.cursorForwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.x = this._terminal.nextStop(); + } + }; + InputHandler.prototype.eraseInDisplay = function (params) { + var j; + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.x, this._terminal.y); + j = this._terminal.y + 1; + for (; j < this._terminal.rows; j++) { + this._terminal.eraseLine(j); + } + break; + case 1: + this._terminal.eraseLeft(this._terminal.x, this._terminal.y); + j = this._terminal.y; + while (j--) { + this._terminal.eraseLine(j); + } + break; + case 2: + j = this._terminal.rows; + while (j--) + this._terminal.eraseLine(j); + break; + case 3: + ; + break; + } + }; + InputHandler.prototype.eraseInLine = function (params) { + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.x, this._terminal.y); + break; + case 1: + this._terminal.eraseLeft(this._terminal.x, this._terminal.y); + break; + case 2: + this._terminal.eraseLine(this._terminal.y); + break; + } + }; + InputHandler.prototype.insertLines = function (params) { + var param, row, j; + param = params[0]; + if (param < 1) { + param = 1; + } + row = this._terminal.y + this._terminal.ybase; + j = this._terminal.rows - 1 - this._terminal.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.ybase - j + 1; + while (param--) { + if (this._terminal.lines.length === this._terminal.lines.maxLength) { + this._terminal.lines.trimStart(1); + this._terminal.ybase--; + this._terminal.ydisp--; + row--; + j--; + } + this._terminal.lines.splice(row, 0, this._terminal.blankLine(true)); + this._terminal.lines.splice(j, 1); + } + this._terminal.updateRange(this._terminal.y); + this._terminal.updateRange(this._terminal.scrollBottom); + }; + InputHandler.prototype.deleteLines = function (params) { + var param, row, j; + param = params[0]; + if (param < 1) { + param = 1; + } + row = this._terminal.y + this._terminal.ybase; + j = this._terminal.rows - 1 - this._terminal.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.ybase - j; + while (param--) { + if (this._terminal.lines.length === this._terminal.lines.maxLength) { + this._terminal.lines.trimStart(1); + this._terminal.ybase -= 1; + this._terminal.ydisp -= 1; + } + this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true)); + this._terminal.lines.splice(row, 1); + } + this._terminal.updateRange(this._terminal.y); + this._terminal.updateRange(this._terminal.scrollBottom); + }; + InputHandler.prototype.deleteChars = function (params) { + var param, row, ch; + param = params[0]; + if (param < 1) { + param = 1; + } + row = this._terminal.y + this._terminal.ybase; + ch = [this._terminal.eraseAttr(), ' ', 1]; + while (param--) { + this._terminal.lines.get(row).splice(this._terminal.x, 1); + this._terminal.lines.get(row).push(ch); + } + }; + InputHandler.prototype.scrollUp = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1); + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine()); + } + this._terminal.updateRange(this._terminal.scrollTop); + this._terminal.updateRange(this._terminal.scrollBottom); + }; + InputHandler.prototype.scrollDown = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1); + this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine()); + } + this._terminal.updateRange(this._terminal.scrollTop); + this._terminal.updateRange(this._terminal.scrollBottom); + }; + InputHandler.prototype.eraseChars = function (params) { + var param, row, j, ch; + param = params[0]; + if (param < 1) { + param = 1; + } + row = this._terminal.y + this._terminal.ybase; + j = this._terminal.x; + ch = [this._terminal.eraseAttr(), ' ', 1]; + while (param-- && j < this._terminal.cols) { + this._terminal.lines.get(row)[j++] = ch; + } + }; + InputHandler.prototype.cursorBackwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.x = this._terminal.prevStop(); + } + }; + InputHandler.prototype.charPosAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x = param - 1; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.HPositionRelative = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.x += param; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.repeatPrecedingCharacter = function (params) { + var param = params[0] || 1, line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y), ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1]; + while (param--) { + line[this._terminal.x++] = ch; + } + }; + InputHandler.prototype.sendDeviceAttributes = function (params) { + if (params[0] > 0) { + return; + } + if (!this._terminal.prefix) { + if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[?1;2c'); + } + else if (this._terminal.is('linux')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[?6c'); + } + } + else if (this._terminal.prefix === '>') { + if (this._terminal.is('xterm')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>0;276;0c'); + } + else if (this._terminal.is('rxvt-unicode')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>85;95;0c'); + } + else if (this._terminal.is('linux')) { + this._terminal.send(params[0] + 'c'); + } + else if (this._terminal.is('screen')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>83;40003;0c'); + } + } + }; + InputHandler.prototype.linePosAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y = param - 1; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + }; + InputHandler.prototype.VPositionRelative = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.y += param; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x--; + } + }; + InputHandler.prototype.HVPosition = function (params) { + if (params[0] < 1) + params[0] = 1; + if (params[1] < 1) + params[1] = 1; + this._terminal.y = params[0] - 1; + if (this._terminal.y >= this._terminal.rows) { + this._terminal.y = this._terminal.rows - 1; + } + this._terminal.x = params[1] - 1; + if (this._terminal.x >= this._terminal.cols) { + this._terminal.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.tabClear = function (params) { + var param = params[0]; + if (param <= 0) { + delete this._terminal.tabs[this._terminal.x]; + } + else if (param === 3) { + this._terminal.tabs = {}; + } + }; + InputHandler.prototype.setMode = function (params) { + if (params.length > 1) { + for (var i = 0; i < params.length; i++) { + this.setMode([params[i]]); + } + return; + } + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = true; + break; + case 20: + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = true; + break; + case 2: + this._terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(1, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(2, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(3, Charsets_1.DEFAULT_CHARSET); + break; + case 3: + this._terminal.savedCols = this._terminal.cols; + this._terminal.resize(132, this._terminal.rows); + break; + case 6: + this._terminal.originMode = true; + break; + case 7: + this._terminal.wraparoundMode = true; + break; + case 12: + break; + case 66: + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + this._terminal.viewport.syncScrollArea(); + break; + case 9: + case 1000: + case 1002: + case 1003: + this._terminal.x10Mouse = params[0] === 9; + this._terminal.vt200Mouse = params[0] === 1000; + this._terminal.normalMouse = params[0] > 1000; + this._terminal.mouseEvents = true; + this._terminal.element.style.cursor = 'default'; + this._terminal.log('Binding to mouse events.'); + break; + case 1004: + this._terminal.sendFocus = true; + break; + case 1005: + this._terminal.utfMouse = true; + break; + case 1006: + this._terminal.sgrMouse = true; + break; + case 1015: + this._terminal.urxvtMouse = true; + break; + case 25: + this._terminal.cursorHidden = false; + break; + case 1049: + ; + case 47: + case 1047: + if (!this._terminal.normal) { + var normal = { + lines: this._terminal.lines, + ybase: this._terminal.ybase, + ydisp: this._terminal.ydisp, + x: this._terminal.x, + y: this._terminal.y, + scrollTop: this._terminal.scrollTop, + scrollBottom: this._terminal.scrollBottom, + tabs: this._terminal.tabs + }; + this._terminal.reset(); + this._terminal.viewport.syncScrollArea(); + this._terminal.normal = normal; + this._terminal.showCursor(); + } + break; + } + } + }; + InputHandler.prototype.resetMode = function (params) { + if (params.length > 1) { + for (var i = 0; i < params.length; i++) { + this.resetMode([params[i]]); + } + return; + } + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = false; + break; + case 20: + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = false; + break; + case 3: + if (this._terminal.cols === 132 && this._terminal.savedCols) { + this._terminal.resize(this._terminal.savedCols, this._terminal.rows); + } + delete this._terminal.savedCols; + break; + case 6: + this._terminal.originMode = false; + break; + case 7: + this._terminal.wraparoundMode = false; + break; + case 12: + break; + case 66: + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + break; + case 9: + case 1000: + case 1002: + case 1003: + this._terminal.x10Mouse = false; + this._terminal.vt200Mouse = false; + this._terminal.normalMouse = false; + this._terminal.mouseEvents = false; + this._terminal.element.style.cursor = ''; + break; + case 1004: + this._terminal.sendFocus = false; + break; + case 1005: + this._terminal.utfMouse = false; + break; + case 1006: + this._terminal.sgrMouse = false; + break; + case 1015: + this._terminal.urxvtMouse = false; + break; + case 25: + this._terminal.cursorHidden = true; + break; + case 1049: + ; + case 47: + case 1047: + if (this._terminal.normal) { + this._terminal.lines = this._terminal.normal.lines; + this._terminal.ybase = this._terminal.normal.ybase; + this._terminal.ydisp = this._terminal.normal.ydisp; + this._terminal.x = this._terminal.normal.x; + this._terminal.y = this._terminal.normal.y; + this._terminal.scrollTop = this._terminal.normal.scrollTop; + this._terminal.scrollBottom = this._terminal.normal.scrollBottom; + this._terminal.tabs = this._terminal.normal.tabs; + this._terminal.normal = null; + this._terminal.refresh(0, this._terminal.rows - 1); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + } + break; + } + } + }; + InputHandler.prototype.charAttributes = function (params) { + if (params.length === 1 && params[0] === 0) { + this._terminal.curAttr = this._terminal.defAttr; + return; + } + var l = params.length, i = 0, flags = this._terminal.curAttr >> 18, fg = (this._terminal.curAttr >> 9) & 0x1ff, bg = this._terminal.curAttr & 0x1ff, p; + for (; i < l; i++) { + p = params[i]; + if (p >= 30 && p <= 37) { + fg = p - 30; + } + else if (p >= 40 && p <= 47) { + bg = p - 40; + } + else if (p >= 90 && p <= 97) { + p += 8; + fg = p - 90; + } + else if (p >= 100 && p <= 107) { + p += 8; + bg = p - 100; + } + else if (p === 0) { + flags = this._terminal.defAttr >> 18; + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } + else if (p === 1) { + flags |= 1; + } + else if (p === 4) { + flags |= 2; + } + else if (p === 5) { + flags |= 4; + } + else if (p === 7) { + flags |= 8; + } + else if (p === 8) { + flags |= 16; + } + else if (p === 22) { + flags &= ~1; + } + else if (p === 24) { + flags &= ~2; + } + else if (p === 25) { + flags &= ~4; + } + else if (p === 27) { + flags &= ~8; + } + else if (p === 28) { + flags &= ~16; + } + else if (p === 39) { + fg = (this._terminal.defAttr >> 9) & 0x1ff; + } + else if (p === 49) { + bg = this._terminal.defAttr & 0x1ff; + } + else if (p === 38) { + if (params[i + 1] === 2) { + i += 2; + fg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (fg === -1) + fg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } + } + else if (p === 48) { + if (params[i + 1] === 2) { + i += 2; + bg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (bg === -1) + bg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } + } + else if (p === 100) { + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } + else { + this._terminal.error('Unknown SGR attribute: %d.', p); + } + } + this._terminal.curAttr = (flags << 18) | (fg << 9) | bg; + }; + InputHandler.prototype.deviceStatus = function (params) { + if (!this._terminal.prefix) { + switch (params[0]) { + case 5: + this._terminal.send(EscapeSequences_1.C0.ESC + '[0n'); + break; + case 6: + this._terminal.send(EscapeSequences_1.C0.ESC + '[' + + (this._terminal.y + 1) + + ';' + + (this._terminal.x + 1) + + 'R'); + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 6: + this._terminal.send(EscapeSequences_1.C0.ESC + '[?' + + (this._terminal.y + 1) + + ';' + + (this._terminal.x + 1) + + 'R'); + break; + case 15: + break; + case 25: + break; + case 26: + break; + case 53: + break; + } + } + }; + InputHandler.prototype.softReset = function (params) { + this._terminal.cursorHidden = false; + this._terminal.insertMode = false; + this._terminal.originMode = false; + this._terminal.wraparoundMode = false; + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + this._terminal.applicationCursor = false; + this._terminal.scrollTop = 0; + this._terminal.scrollBottom = this._terminal.rows - 1; + this._terminal.curAttr = this._terminal.defAttr; + this._terminal.x = this._terminal.y = 0; + this._terminal.charset = null; + this._terminal.glevel = 0; + this._terminal.charsets = [null]; + }; + InputHandler.prototype.setCursorStyle = function (params) { + var param = params[0] < 1 ? 1 : params[0]; + switch (param) { + case 1: + case 2: + this._terminal.setOption('cursorStyle', 'block'); + break; + case 3: + case 4: + this._terminal.setOption('cursorStyle', 'underline'); + break; + case 5: + case 6: + this._terminal.setOption('cursorStyle', 'bar'); + break; + } + var isBlinking = param % 2 === 1; + this._terminal.setOption('cursorBlink', isBlinking); + }; + InputHandler.prototype.setScrollRegion = function (params) { + if (this._terminal.prefix) + return; + this._terminal.scrollTop = (params[0] || 1) - 1; + this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1; + this._terminal.x = 0; + this._terminal.y = 0; + }; + InputHandler.prototype.saveCursor = function (params) { + this._terminal.savedX = this._terminal.x; + this._terminal.savedY = this._terminal.y; + }; + InputHandler.prototype.restoreCursor = function (params) { + this._terminal.x = this._terminal.savedX || 0; + this._terminal.y = this._terminal.savedY || 0; + }; + return InputHandler; +}()); +exports.InputHandler = InputHandler; var wcwidth = (function (opts) { - // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c - // combining characters var COMBINING = [ [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], @@ -5094,7 +1256,6 @@ var wcwidth = (function (opts) { [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], [0xE0100, 0xE01EF] ]; - // binary search function bisearch(ucs) { var min = 0; var max = COMBINING.length - 1; @@ -5113,48 +1274,2597 @@ var wcwidth = (function (opts) { return false; } function wcwidth(ucs) { - // test for 8-bit control characters if (ucs === 0) return opts.nul; if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return opts.control; - // binary search in table of non-spacing characters if (bisearch(ucs)) return 0; - // if we arrive here, ucs is not a combining or C0/C1 control character - return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || - ucs == 0x2329 || - ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || - (ucs >= 0xac00 && ucs <= 0xd7a3) || - (ucs >= 0xf900 && ucs <= 0xfaff) || - (ucs >= 0xfe10 && ucs <= 0xfe19) || - (ucs >= 0xfe30 && ucs <= 0xfe6f) || - (ucs >= 0xff00 && ucs <= 0xff60) || - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); + if (isWide(ucs)) { + return 2; + } + return 1; + } + function isWide(ucs) { + return (ucs >= 0x1100 && (ucs <= 0x115f || + ucs === 0x2329 || + ucs === 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || + (ucs >= 0xac00 && ucs <= 0xd7a3) || + (ucs >= 0xf900 && ucs <= 0xfaff) || + (ucs >= 0xfe10 && ucs <= 0xfe19) || + (ucs >= 0xfe30 && ucs <= 0xfe6f) || + (ucs >= 0xff00 && ucs <= 0xff60) || + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); } return wcwidth; -})({ nul: 0, control: 0 }); // configurable options -/** - * Expose - */ -Terminal.EventEmitter = EventEmitter_js_1.EventEmitter; +})({ nul: 0, control: 0 }); + +},{"./Charsets":1,"./EscapeSequences":3}],6:[function(require,module,exports){ +"use strict"; +var EscapeSequences_1 = require("./EscapeSequences"); +var Charsets_1 = require("./Charsets"); +var normalStateHandler = {}; +normalStateHandler[EscapeSequences_1.C0.BEL] = function (parser, handler) { return handler.bell(); }; +normalStateHandler[EscapeSequences_1.C0.LF] = function (parser, handler) { return handler.lineFeed(); }; +normalStateHandler[EscapeSequences_1.C0.VT] = normalStateHandler[EscapeSequences_1.C0.LF]; +normalStateHandler[EscapeSequences_1.C0.FF] = normalStateHandler[EscapeSequences_1.C0.LF]; +normalStateHandler[EscapeSequences_1.C0.CR] = function (parser, handler) { return handler.carriageReturn(); }; +normalStateHandler[EscapeSequences_1.C0.BS] = function (parser, handler) { return handler.backspace(); }; +normalStateHandler[EscapeSequences_1.C0.HT] = function (parser, handler) { return handler.tab(); }; +normalStateHandler[EscapeSequences_1.C0.SO] = function (parser, handler) { return handler.shiftOut(); }; +normalStateHandler[EscapeSequences_1.C0.SI] = function (parser, handler) { return handler.shiftIn(); }; +normalStateHandler[EscapeSequences_1.C0.ESC] = function (parser, handler) { return parser.setState(ParserState.ESCAPED); }; +var escapedStateHandler = {}; +escapedStateHandler['['] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.CSI_PARAM); +}; +escapedStateHandler[']'] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.OSC); +}; +escapedStateHandler['P'] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.DCS); +}; +escapedStateHandler['_'] = function (parser, terminal) { + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['^'] = function (parser, terminal) { + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['c'] = function (parser, terminal) { + terminal.reset(); +}; +escapedStateHandler['E'] = function (parser, terminal) { + terminal.x = 0; + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['D'] = function (parser, terminal) { + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['M'] = function (parser, terminal) { + terminal.reverseIndex(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['%'] = function (parser, terminal) { + terminal.setgLevel(0); + terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET); + parser.setState(ParserState.NORMAL); + parser.skipNextChar(); +}; +escapedStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); }; +var csiParamStateHandler = {}; +csiParamStateHandler['?'] = function (parser) { return parser.setPrefix('?'); }; +csiParamStateHandler['>'] = function (parser) { return parser.setPrefix('>'); }; +csiParamStateHandler['!'] = function (parser) { return parser.setPrefix('!'); }; +csiParamStateHandler['0'] = function (parser) { return parser.setParam(parser.getParam() * 10); }; +csiParamStateHandler['1'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 1); }; +csiParamStateHandler['2'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 2); }; +csiParamStateHandler['3'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 3); }; +csiParamStateHandler['4'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 4); }; +csiParamStateHandler['5'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 5); }; +csiParamStateHandler['6'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 6); }; +csiParamStateHandler['7'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 7); }; +csiParamStateHandler['8'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 8); }; +csiParamStateHandler['9'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 9); }; +csiParamStateHandler['$'] = function (parser) { return parser.setPostfix('$'); }; +csiParamStateHandler['"'] = function (parser) { return parser.setPostfix('"'); }; +csiParamStateHandler[' '] = function (parser) { return parser.setPostfix(' '); }; +csiParamStateHandler['\''] = function (parser) { return parser.setPostfix('\''); }; +csiParamStateHandler[';'] = function (parser) { return parser.finalizeParam(); }; +csiParamStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); }; +var csiStateHandler = {}; +csiStateHandler['@'] = function (handler, params, prefix) { return handler.insertChars(params); }; +csiStateHandler['A'] = function (handler, params, prefix) { return handler.cursorUp(params); }; +csiStateHandler['B'] = function (handler, params, prefix) { return handler.cursorDown(params); }; +csiStateHandler['C'] = function (handler, params, prefix) { return handler.cursorForward(params); }; +csiStateHandler['D'] = function (handler, params, prefix) { return handler.cursorBackward(params); }; +csiStateHandler['E'] = function (handler, params, prefix) { return handler.cursorNextLine(params); }; +csiStateHandler['F'] = function (handler, params, prefix) { return handler.cursorPrecedingLine(params); }; +csiStateHandler['G'] = function (handler, params, prefix) { return handler.cursorCharAbsolute(params); }; +csiStateHandler['H'] = function (handler, params, prefix) { return handler.cursorPosition(params); }; +csiStateHandler['I'] = function (handler, params, prefix) { return handler.cursorForwardTab(params); }; +csiStateHandler['J'] = function (handler, params, prefix) { return handler.eraseInDisplay(params); }; +csiStateHandler['K'] = function (handler, params, prefix) { return handler.eraseInLine(params); }; +csiStateHandler['L'] = function (handler, params, prefix) { return handler.insertLines(params); }; +csiStateHandler['M'] = function (handler, params, prefix) { return handler.deleteLines(params); }; +csiStateHandler['P'] = function (handler, params, prefix) { return handler.deleteChars(params); }; +csiStateHandler['S'] = function (handler, params, prefix) { return handler.scrollUp(params); }; +csiStateHandler['T'] = function (handler, params, prefix) { + if (params.length < 2 && !prefix) { + handler.scrollDown(params); + } +}; +csiStateHandler['X'] = function (handler, params, prefix) { return handler.eraseChars(params); }; +csiStateHandler['Z'] = function (handler, params, prefix) { return handler.cursorBackwardTab(params); }; +csiStateHandler['`'] = function (handler, params, prefix) { return handler.charPosAbsolute(params); }; +csiStateHandler['a'] = function (handler, params, prefix) { return handler.HPositionRelative(params); }; +csiStateHandler['b'] = function (handler, params, prefix) { return handler.repeatPrecedingCharacter(params); }; +csiStateHandler['c'] = function (handler, params, prefix) { return handler.sendDeviceAttributes(params); }; +csiStateHandler['d'] = function (handler, params, prefix) { return handler.linePosAbsolute(params); }; +csiStateHandler['e'] = function (handler, params, prefix) { return handler.VPositionRelative(params); }; +csiStateHandler['f'] = function (handler, params, prefix) { return handler.HVPosition(params); }; +csiStateHandler['g'] = function (handler, params, prefix) { return handler.tabClear(params); }; +csiStateHandler['h'] = function (handler, params, prefix) { return handler.setMode(params); }; +csiStateHandler['l'] = function (handler, params, prefix) { return handler.resetMode(params); }; +csiStateHandler['m'] = function (handler, params, prefix) { return handler.charAttributes(params); }; +csiStateHandler['n'] = function (handler, params, prefix) { return handler.deviceStatus(params); }; +csiStateHandler['p'] = function (handler, params, prefix) { + switch (prefix) { + case '!': + handler.softReset(params); + break; + } +}; +csiStateHandler['q'] = function (handler, params, prefix, postfix) { + if (postfix === ' ') { + handler.setCursorStyle(params); + } +}; +csiStateHandler['r'] = function (handler, params) { return handler.setScrollRegion(params); }; +csiStateHandler['s'] = function (handler, params) { return handler.saveCursor(params); }; +csiStateHandler['u'] = function (handler, params) { return handler.restoreCursor(params); }; +csiStateHandler[EscapeSequences_1.C0.CAN] = function (handler, params, prefix, postfix, parser) { return parser.setState(ParserState.NORMAL); }; +var ParserState; +(function (ParserState) { + ParserState[ParserState["NORMAL"] = 0] = "NORMAL"; + ParserState[ParserState["ESCAPED"] = 1] = "ESCAPED"; + ParserState[ParserState["CSI_PARAM"] = 2] = "CSI_PARAM"; + ParserState[ParserState["CSI"] = 3] = "CSI"; + ParserState[ParserState["OSC"] = 4] = "OSC"; + ParserState[ParserState["CHARSET"] = 5] = "CHARSET"; + ParserState[ParserState["DCS"] = 6] = "DCS"; + ParserState[ParserState["IGNORE"] = 7] = "IGNORE"; +})(ParserState || (ParserState = {})); +var Parser = (function () { + function Parser(_inputHandler, _terminal) { + this._inputHandler = _inputHandler; + this._terminal = _terminal; + this._state = ParserState.NORMAL; + } + Parser.prototype.parse = function (data) { + var l = data.length, j, cs, ch, code, low; + this._position = 0; + if (this._terminal.surrogate_high) { + data = this._terminal.surrogate_high + data; + this._terminal.surrogate_high = ''; + } + for (; this._position < l; this._position++) { + ch = data[this._position]; + code = data.charCodeAt(this._position); + if (0xD800 <= code && code <= 0xDBFF) { + low = data.charCodeAt(this._position + 1); + if (isNaN(low)) { + this._terminal.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(this._position + 1); + } + if (0xDC00 <= code && code <= 0xDFFF) + continue; + switch (this._state) { + case ParserState.NORMAL: + if (ch in normalStateHandler) { + normalStateHandler[ch](this, this._inputHandler); + } + else { + this._inputHandler.addChar(ch, code); + } + break; + case ParserState.ESCAPED: + if (ch in escapedStateHandler) { + escapedStateHandler[ch](this, this._terminal); + break; + } + switch (ch) { + case '(': + case ')': + case '*': + case '+': + case '-': + case '.': + switch (ch) { + case '(': + this._terminal.gcharset = 0; + break; + case ')': + this._terminal.gcharset = 1; + break; + case '*': + this._terminal.gcharset = 2; + break; + case '+': + this._terminal.gcharset = 3; + break; + case '-': + this._terminal.gcharset = 1; + break; + case '.': + this._terminal.gcharset = 2; + break; + } + this._state = ParserState.CHARSET; + break; + case '/': + this._terminal.gcharset = 3; + this._state = ParserState.CHARSET; + this._position--; + break; + case 'N': + break; + case 'O': + break; + case 'n': + this._terminal.setgLevel(2); + break; + case 'o': + this._terminal.setgLevel(3); + break; + case '|': + this._terminal.setgLevel(3); + break; + case '}': + this._terminal.setgLevel(2); + break; + case '~': + this._terminal.setgLevel(1); + break; + case '7': + this._inputHandler.saveCursor(); + this._state = ParserState.NORMAL; + break; + case '8': + this._inputHandler.restoreCursor(); + this._state = ParserState.NORMAL; + break; + case '#': + this._state = ParserState.NORMAL; + this._position++; + break; + case 'H': + this._terminal.tabSet(); + this._state = ParserState.NORMAL; + break; + case '=': + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + this._terminal.viewport.syncScrollArea(); + this._state = ParserState.NORMAL; + break; + case '>': + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + this._state = ParserState.NORMAL; + break; + default: + this._state = ParserState.NORMAL; + this._terminal.error('Unknown ESC control: %s.', ch); + break; + } + break; + case ParserState.CHARSET: + if (ch in Charsets_1.CHARSETS) { + cs = Charsets_1.CHARSETS[ch]; + if (ch === '/') { + this.skipNextChar(); + } + } + else { + cs = Charsets_1.DEFAULT_CHARSET; + } + this._terminal.setgCharset(this._terminal.gcharset, cs); + this._terminal.gcharset = null; + this._state = ParserState.NORMAL; + break; + case ParserState.OSC: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + this._terminal.params.push(this._terminal.currentParam); + switch (this._terminal.params[0]) { + case 0: + case 1: + case 2: + if (this._terminal.params[1]) { + this._terminal.title = this._terminal.params[1]; + this._terminal.handleTitle(this._terminal.title); + } + break; + case 3: + break; + case 4: + case 5: + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + break; + case 46: + break; + case 50: + break; + case 51: + break; + case 52: + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + break; + } + this._terminal.params = []; + this._terminal.currentParam = 0; + this._state = ParserState.NORMAL; + } + else { + if (!this._terminal.params.length) { + if (ch >= '0' && ch <= '9') { + this._terminal.currentParam = + this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; + } + else if (ch === ';') { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = ''; + } + } + else { + this._terminal.currentParam += ch; + } + } + break; + case ParserState.CSI_PARAM: + if (ch in csiParamStateHandler) { + csiParamStateHandler[ch](this); + break; + } + this.finalizeParam(); + this._state = ParserState.CSI; + case ParserState.CSI: + if (ch in csiStateHandler) { + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this); + } + else { + this._terminal.error('Unknown CSI code: %s.', ch); + } + this._state = ParserState.NORMAL; + this._terminal.prefix = ''; + this._terminal.postfix = ''; + break; + case ParserState.DCS: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + switch (this._terminal.prefix) { + case '': + break; + case '$q': + var pt = this._terminal.currentParam, valid = false; + switch (pt) { + case '"q': + pt = '0"q'; + break; + case '"p': + pt = '61"p'; + break; + case 'r': + pt = '' + + (this._terminal.scrollTop + 1) + + ';' + + (this._terminal.scrollBottom + 1) + + 'r'; + break; + case 'm': + pt = '0m'; + break; + default: + this._terminal.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '$r' + pt + EscapeSequences_1.C0.ESC + '\\'); + break; + case '+p': + break; + case '+q': + pt = this._terminal.currentParam + , valid = false; + this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '+r' + pt + EscapeSequences_1.C0.ESC + '\\'); + break; + default: + this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix); + break; + } + this._terminal.currentParam = 0; + this._terminal.prefix = ''; + this._state = ParserState.NORMAL; + } + else if (!this._terminal.currentParam) { + if (!this._terminal.prefix && ch !== '$' && ch !== '+') { + this._terminal.currentParam = ch; + } + else if (this._terminal.prefix.length === 2) { + this._terminal.currentParam = ch; + } + else { + this._terminal.prefix += ch; + } + } + else { + this._terminal.currentParam += ch; + } + break; + case ParserState.IGNORE: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + this._state = ParserState.NORMAL; + } + break; + } + } + }; + Parser.prototype.setState = function (state) { + this._state = state; + }; + Parser.prototype.setPrefix = function (prefix) { + this._terminal.prefix = prefix; + }; + Parser.prototype.setPostfix = function (postfix) { + this._terminal.postfix = postfix; + }; + Parser.prototype.setParam = function (param) { + this._terminal.currentParam = param; + }; + Parser.prototype.getParam = function () { + return this._terminal.currentParam; + }; + Parser.prototype.finalizeParam = function () { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = 0; + }; + Parser.prototype.skipNextChar = function () { + this._position++; + }; + return Parser; +}()); +exports.Parser = Parser; + +},{"./Charsets":1,"./EscapeSequences":3}],7:[function(require,module,exports){ +"use strict"; +var MAX_REFRESH_FRAME_SKIP = 5; +var FLAGS; +(function (FLAGS) { + FLAGS[FLAGS["BOLD"] = 1] = "BOLD"; + FLAGS[FLAGS["UNDERLINE"] = 2] = "UNDERLINE"; + FLAGS[FLAGS["BLINK"] = 4] = "BLINK"; + FLAGS[FLAGS["INVERSE"] = 8] = "INVERSE"; + FLAGS[FLAGS["INVISIBLE"] = 16] = "INVISIBLE"; +})(FLAGS || (FLAGS = {})); +; +var brokenBold = null; +var Renderer = (function () { + function Renderer(_terminal) { + this._terminal = _terminal; + this._refreshRowsQueue = []; + this._refreshFramesSkipped = 0; + this._refreshAnimationFrame = null; + if (brokenBold === null) { + brokenBold = checkBoldBroken(this._terminal.document); + } + } + Renderer.prototype.queueRefresh = function (start, end) { + this._refreshRowsQueue.push({ start: start, end: end }); + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + } + }; + Renderer.prototype._refreshLoop = function () { + var skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP; + if (skipFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + return; + } + this._refreshFramesSkipped = 0; + var start; + var end; + if (this._refreshRowsQueue.length > 4) { + start = 0; + end = this._terminal.rows - 1; + } + else { + start = this._refreshRowsQueue[0].start; + end = this._refreshRowsQueue[0].end; + for (var i = 1; i < this._refreshRowsQueue.length; i++) { + if (this._refreshRowsQueue[i].start < start) { + start = this._refreshRowsQueue[i].start; + } + if (this._refreshRowsQueue[i].end > end) { + end = this._refreshRowsQueue[i].end; + } + } + } + this._refreshRowsQueue = []; + this._refreshAnimationFrame = null; + this._refresh(start, end); + }; + Renderer.prototype._refresh = function (start, end) { + var x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement; + if (end - start >= this._terminal.rows / 2) { + parent = this._terminal.element.parentNode; + if (parent) { + this._terminal.element.removeChild(this._terminal.rowContainer); + } + } + width = this._terminal.cols; + y = start; + if (end >= this._terminal.rows) { + this._terminal.log('`end` is too large. Most likely a bad CSR.'); + end = this._terminal.rows - 1; + } + for (; y <= end; y++) { + row = y + this._terminal.ydisp; + line = this._terminal.lines.get(row); + if (!line || !this._terminal.children[y]) { + continue; + } + out = ''; + if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp) + && this._terminal.cursorState + && !this._terminal.cursorHidden) { + x = this._terminal.x; + } + else { + x = -1; + } + attr = this._terminal.defAttr; + i = 0; + for (; i < width; i++) { + if (!line[i]) { + continue; + } + data = line[i][0]; + ch = line[i][1]; + ch_width = line[i][2]; + if (!ch_width) + continue; + if (i === x) + data = -1; + if (data !== attr) { + if (attr !== this._terminal.defAttr) { + out += ''; + } + if (data !== this._terminal.defAttr) { + if (data === -1) { + out += ''; + } + else { + var classNames = []; + bg = data & 0x1ff; + fg = (data >> 9) & 0x1ff; + flags = data >> 18; + if (flags & FLAGS.BOLD) { + if (!brokenBold) { + classNames.push('xterm-bold'); + } + if (fg < 8) + fg += 8; + } + if (flags & FLAGS.UNDERLINE) { + classNames.push('xterm-underline'); + } + if (flags & FLAGS.BLINK) { + classNames.push('xterm-blink'); + } + if (flags & FLAGS.INVERSE) { + bg = [fg, fg = bg][0]; + if ((flags & 1) && fg < 8) + fg += 8; + } + if (flags & FLAGS.INVISIBLE) { + classNames.push('xterm-hidden'); + } + if (flags & FLAGS.INVERSE) { + if (bg === 257) { + bg = 15; + } + if (fg === 256) { + fg = 0; + } + } + if (bg < 256) { + classNames.push('xterm-bg-color-' + bg); + } + if (fg < 256) { + classNames.push('xterm-color-' + fg); + } + out += '': + out += '>'; + break; + default: + if (ch <= ' ') { + out += ' '; + } + else { + out += ch; + } + break; + } + if (ch_width === 2) { + out += ''; + } + attr = data; + } + if (attr !== this._terminal.defAttr) { + out += ''; + } + this._terminal.children[y].innerHTML = out; + } + if (parent) { + this._terminal.element.appendChild(this._terminal.rowContainer); + } + this._terminal.emit('refresh', { element: this._terminal.element, start: start, end: end }); + }; + ; + return Renderer; +}()); +exports.Renderer = Renderer; +function checkBoldBroken(document) { + var body = document.getElementsByTagName('body')[0]; + var el = document.createElement('span'); + el.innerHTML = 'hello world'; + body.appendChild(el); + var w1 = el.scrollWidth; + el.style.fontWeight = 'bold'; + var w2 = el.scrollWidth; + body.removeChild(el); + return w1 !== w2; +} + +},{}],8:[function(require,module,exports){ +"use strict"; +var Viewport = (function () { + function Viewport(terminal, viewportElement, scrollArea, charMeasure) { + this.terminal = terminal; + this.viewportElement = viewportElement; + this.scrollArea = scrollArea; + this.charMeasure = charMeasure; + this.currentRowHeight = 0; + this.lastRecordedBufferLength = 0; + this.lastRecordedViewportHeight = 0; + this.terminal.on('scroll', this.syncScrollArea.bind(this)); + this.terminal.on('resize', this.syncScrollArea.bind(this)); + this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); + this.syncScrollArea(); + } + Viewport.prototype.refresh = function () { + if (this.charMeasure.height > 0) { + var rowHeightChanged = this.charMeasure.height !== this.currentRowHeight; + if (rowHeightChanged) { + this.currentRowHeight = this.charMeasure.height; + this.viewportElement.style.lineHeight = this.charMeasure.height + 'px'; + this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px'; + } + var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows; + if (rowHeightChanged || viewportHeightChanged) { + this.lastRecordedViewportHeight = this.terminal.rows; + this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px'; + } + this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px'; + } + }; + Viewport.prototype.syncScrollArea = function () { + if (this.lastRecordedBufferLength !== this.terminal.lines.length) { + this.lastRecordedBufferLength = this.terminal.lines.length; + this.refresh(); + } + else if (this.lastRecordedViewportHeight !== this.terminal.rows) { + this.refresh(); + } + else { + if (this.charMeasure.height !== this.currentRowHeight) { + this.refresh(); + } + } + var scrollTop = this.terminal.ydisp * this.currentRowHeight; + if (this.viewportElement.scrollTop !== scrollTop) { + this.viewportElement.scrollTop = scrollTop; + } + }; + Viewport.prototype.onScroll = function (ev) { + var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); + var diff = newRow - this.terminal.ydisp; + this.terminal.scrollDisp(diff, true); + }; + Viewport.prototype.onWheel = function (ev) { + if (ev.deltaY === 0) { + return; + } + var multiplier = 1; + if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { + multiplier = this.currentRowHeight; + } + else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { + multiplier = this.currentRowHeight * this.terminal.rows; + } + this.viewportElement.scrollTop += ev.deltaY * multiplier; + ev.preventDefault(); + }; + ; + return Viewport; +}()); +exports.Viewport = Viewport; + +},{}],9:[function(require,module,exports){ +"use strict"; +function prepareTextForClipboard(text) { + var space = String.fromCharCode(32), nonBreakingSpace = String.fromCharCode(160), allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'), processedText = text.split('\n').map(function (line) { + var processedLine = line.replace(/\s+$/g, '').replace(allNonBreakingSpaces, space); + return processedLine; + }).join('\n'); + return processedText; +} +exports.prepareTextForClipboard = prepareTextForClipboard; +function copyHandler(ev, term) { + var copiedText = window.getSelection().toString(), text = prepareTextForClipboard(copiedText); + if (term.browser.isMSIE) { + window.clipboardData.setData('Text', text); + } + else { + ev.clipboardData.setData('text/plain', text); + } + ev.preventDefault(); +} +exports.copyHandler = copyHandler; +function pasteHandler(ev, term) { + ev.stopPropagation(); + var text; + var dispatchPaste = function (text) { + term.handler(text); + term.textarea.value = ''; + return term.cancel(ev); + }; + if (term.browser.isMSIE) { + if (window.clipboardData) { + text = window.clipboardData.getData('Text'); + dispatchPaste(text); + } + } + else { + if (ev.clipboardData) { + text = ev.clipboardData.getData('text/plain'); + dispatchPaste(text); + } + } +} +exports.pasteHandler = pasteHandler; +function rightClickHandler(ev, term) { + var s = document.getSelection(), selectedText = prepareTextForClipboard(s.toString()), clickIsOnSelection = false, x = ev.clientX, y = ev.clientY; + if (s.rangeCount) { + var r = s.getRangeAt(0), cr = r.getClientRects(); + for (var i = 0; i < cr.length; i++) { + var rect = cr[i]; + clickIsOnSelection = ((x > rect.left) && (x < rect.right) && + (y > rect.top) && (y < rect.bottom)); + if (clickIsOnSelection) { + break; + } + } + if (selectedText.match(/^\s$/) || !selectedText.length) { + clickIsOnSelection = false; + } + } + if (!clickIsOnSelection) { + term.textarea.style.position = 'fixed'; + term.textarea.style.width = '20px'; + term.textarea.style.height = '20px'; + term.textarea.style.left = (x - 10) + 'px'; + term.textarea.style.top = (y - 10) + 'px'; + term.textarea.style.zIndex = '1000'; + term.textarea.focus(); + setTimeout(function () { + term.textarea.style.position = null; + term.textarea.style.width = null; + term.textarea.style.height = null; + term.textarea.style.left = null; + term.textarea.style.top = null; + term.textarea.style.zIndex = null; + }, 4); + } +} +exports.rightClickHandler = rightClickHandler; + +},{}],10:[function(require,module,exports){ +"use strict"; +var Generic_1 = require("./Generic"); +var isNode = (typeof navigator === 'undefined') ? true : false; +var userAgent = (isNode) ? 'node' : navigator.userAgent; +var platform = (isNode) ? 'node' : navigator.platform; +exports.isFirefox = !!~userAgent.indexOf('Firefox'); +exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident'); +exports.isMac = Generic_1.contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform); +exports.isIpad = platform === 'iPad'; +exports.isIphone = platform === 'iPhone'; +exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); + +},{"./Generic":13}],11:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) + if (b.hasOwnProperty(p)) + d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var EventEmitter_js_1 = require("../EventEmitter.js"); +var CharMeasure = (function (_super) { + __extends(CharMeasure, _super); + function CharMeasure(parentElement) { + var _this = _super.call(this) || this; + _this._parentElement = parentElement; + return _this; + } + Object.defineProperty(CharMeasure.prototype, "width", { + get: function () { + return this._width; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CharMeasure.prototype, "height", { + get: function () { + return this._height; + }, + enumerable: true, + configurable: true + }); + CharMeasure.prototype.measure = function () { + var _this = this; + if (!this._measureElement) { + this._measureElement = document.createElement('span'); + this._measureElement.style.position = 'absolute'; + this._measureElement.style.top = '0'; + this._measureElement.style.left = '-9999em'; + this._measureElement.textContent = 'W'; + this._parentElement.appendChild(this._measureElement); + setTimeout(function () { return _this._doMeasure(); }, 0); + } + else { + this._doMeasure(); + } + }; + CharMeasure.prototype._doMeasure = function () { + var geometry = this._measureElement.getBoundingClientRect(); + if (geometry.width === 0 || geometry.height === 0) { + return; + } + if (this._width !== geometry.width || this._height !== geometry.height) { + this._width = geometry.width; + this._height = geometry.height; + this.emit('charsizechanged'); + } + }; + return CharMeasure; +}(EventEmitter_js_1.EventEmitter)); +exports.CharMeasure = CharMeasure; + +},{"../EventEmitter.js":4}],12:[function(require,module,exports){ +"use strict"; +var CircularList = (function () { + function CircularList(maxLength) { + this._array = new Array(maxLength); + this._startIndex = 0; + this._length = 0; + } + Object.defineProperty(CircularList.prototype, "maxLength", { + get: function () { + return this._array.length; + }, + set: function (newMaxLength) { + var newArray = new Array(newMaxLength); + for (var i = 0; i < Math.min(newMaxLength, this.length); i++) { + newArray[i] = this._array[this._getCyclicIndex(i)]; + } + this._array = newArray; + this._startIndex = 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CircularList.prototype, "length", { + get: function () { + return this._length; + }, + set: function (newLength) { + if (newLength > this._length) { + for (var i = this._length; i < newLength; i++) { + this._array[i] = undefined; + } + } + this._length = newLength; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CircularList.prototype, "forEach", { + get: function () { + return this._array.forEach; + }, + enumerable: true, + configurable: true + }); + CircularList.prototype.get = function (index) { + return this._array[this._getCyclicIndex(index)]; + }; + CircularList.prototype.set = function (index, value) { + this._array[this._getCyclicIndex(index)] = value; + }; + CircularList.prototype.push = function (value) { + this._array[this._getCyclicIndex(this._length)] = value; + if (this._length === this.maxLength) { + this._startIndex++; + if (this._startIndex === this.maxLength) { + this._startIndex = 0; + } + } + else { + this._length++; + } + }; + CircularList.prototype.pop = function () { + return this._array[this._getCyclicIndex(this._length-- - 1)]; + }; + CircularList.prototype.splice = function (start, deleteCount) { + var items = []; + for (var _i = 2; _i < arguments.length; _i++) { + items[_i - 2] = arguments[_i]; + } + if (deleteCount) { + for (var i = start; i < this._length - deleteCount; i++) { + this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)]; + } + this._length -= deleteCount; + } + if (items && items.length) { + for (var i = this._length - 1; i >= start; i--) { + this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)]; + } + for (var i = 0; i < items.length; i++) { + this._array[this._getCyclicIndex(start + i)] = items[i]; + } + if (this._length + items.length > this.maxLength) { + this._startIndex += (this._length + items.length) - this.maxLength; + this._length = this.maxLength; + } + else { + this._length += items.length; + } + } + }; + CircularList.prototype.trimStart = function (count) { + if (count > this._length) { + count = this._length; + } + this._startIndex += count; + this._length -= count; + }; + CircularList.prototype.shiftElements = function (start, count, offset) { + if (count <= 0) { + return; + } + if (start < 0 || start >= this._length) { + throw new Error('start argument out of range'); + } + if (start + offset < 0) { + throw new Error('Cannot shift elements in list beyond index 0'); + } + if (offset > 0) { + for (var i = count - 1; i >= 0; i--) { + this.set(start + i + offset, this.get(start + i)); + } + var expandListBy = (start + count + offset) - this._length; + if (expandListBy > 0) { + this._length += expandListBy; + while (this._length > this.maxLength) { + this._length--; + this._startIndex++; + } + } + } + else { + for (var i = 0; i < count; i++) { + this.set(start + i + offset, this.get(start + i)); + } + } + }; + CircularList.prototype._getCyclicIndex = function (index) { + return (this._startIndex + index) % this.maxLength; + }; + return CircularList; +}()); +exports.CircularList = CircularList; + +},{}],13:[function(require,module,exports){ +"use strict"; +function contains(arr, el) { + return arr.indexOf(el) >= 0; +} +exports.contains = contains; +; + +},{}],14:[function(require,module,exports){ +"use strict"; +var CompositionHelper_1 = require("./CompositionHelper"); +var EventEmitter_1 = require("./EventEmitter"); +var Viewport_1 = require("./Viewport"); +var Clipboard_1 = require("./handlers/Clipboard"); +var CircularList_1 = require("./utils/CircularList"); +var EscapeSequences_1 = require("./EscapeSequences"); +var InputHandler_1 = require("./InputHandler"); +var Parser_1 = require("./Parser"); +var Renderer_1 = require("./Renderer"); +var CharMeasure_1 = require("./utils/CharMeasure"); +var Browser = require("./utils/Browser"); +var document = (typeof window != 'undefined') ? window.document : null; +var WRITE_BUFFER_PAUSE_THRESHOLD = 5; +var WRITE_BATCH_SIZE = 300; +function Terminal(options) { + var self = this; + if (!(this instanceof Terminal)) { + return new Terminal(arguments[0], arguments[1], arguments[2]); + } + self.browser = Browser; + self.cancel = Terminal.cancel; + EventEmitter_1.EventEmitter.call(this); + if (typeof options === 'number') { + options = { + cols: arguments[0], + rows: arguments[1], + handler: arguments[2] + }; + } + options = options || {}; + Object.keys(Terminal.defaults).forEach(function (key) { + if (options[key] == null) { + options[key] = Terminal.options[key]; + if (Terminal[key] !== Terminal.defaults[key]) { + options[key] = Terminal[key]; + } + } + self[key] = options[key]; + }); + if (options.colors.length === 8) { + options.colors = options.colors.concat(Terminal._colors.slice(8)); + } + else if (options.colors.length === 16) { + options.colors = options.colors.concat(Terminal._colors.slice(16)); + } + else if (options.colors.length === 10) { + options.colors = options.colors.slice(0, -2).concat(Terminal._colors.slice(8, -2), options.colors.slice(-2)); + } + else if (options.colors.length === 18) { + options.colors = options.colors.concat(Terminal._colors.slice(16, -2), options.colors.slice(-2)); + } + this.colors = options.colors; + this.options = options; + this.parent = options.body || options.parent || (document ? document.getElementsByTagName('body')[0] : null); + this.cols = options.cols || options.geometry[0]; + this.rows = options.rows || options.geometry[1]; + this.geometry = [this.cols, this.rows]; + if (options.handler) { + this.on('data', options.handler); + } + this.ybase = 0; + this.ydisp = 0; + this.x = 0; + this.y = 0; + this.cursorState = 0; + this.cursorHidden = false; + this.convertEol; + this.queue = ''; + this.scrollTop = 0; + this.scrollBottom = this.rows - 1; + this.customKeydownHandler = null; + this.applicationKeypad = false; + this.applicationCursor = false; + this.originMode = false; + this.insertMode = false; + this.wraparoundMode = true; + this.normal = null; + this.charset = null; + this.gcharset = null; + this.glevel = 0; + this.charsets = [null]; + this.decLocator; + this.x10Mouse; + this.vt200Mouse; + this.vt300Mouse; + this.normalMouse; + this.mouseEvents; + this.sendFocus; + this.utfMouse; + this.sgrMouse; + this.urxvtMouse; + this.element; + this.children; + this.refreshStart; + this.refreshEnd; + this.savedX; + this.savedY; + this.savedCols; + this.readable = true; + this.writable = true; + this.defAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.curAttr = this.defAttr; + this.params = []; + this.currentParam = 0; + this.prefix = ''; + this.postfix = ''; + this.inputHandler = new InputHandler_1.InputHandler(this); + this.parser = new Parser_1.Parser(this.inputHandler, this); + this.renderer = this.renderer || null; + this.writeBuffer = []; + this.writeInProgress = false; + this.xoffSentToCatchUp = false; + this.writeStopped = false; + this.surrogate_high = ''; + this.lines = new CircularList_1.CircularList(this.scrollback); + var i = this.rows; + while (i--) { + this.lines.push(this.blankLine()); + } + this.tabs; + this.setupStops(); + this.userScrolling = false; +} +inherits(Terminal, EventEmitter_1.EventEmitter); +Terminal.prototype.eraseAttr = function () { + return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff); +}; +Terminal.tangoColors = [ + '#2e3436', + '#cc0000', + '#4e9a06', + '#c4a000', + '#3465a4', + '#75507b', + '#06989a', + '#d3d7cf', + '#555753', + '#ef2929', + '#8ae234', + '#fce94f', + '#729fcf', + '#ad7fa8', + '#34e2e2', + '#eeeeec' +]; +Terminal.colors = (function () { + var colors = Terminal.tangoColors.slice(), r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff], i; + i = 0; + for (; i < 216; i++) { + out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]); + } + i = 0; + for (; i < 24; i++) { + r = 8 + i * 10; + out(r, r, r); + } + function out(r, g, b) { + colors.push('#' + hex(r) + hex(g) + hex(b)); + } + function hex(c) { + c = c.toString(16); + return c.length < 2 ? '0' + c : c; + } + return colors; +})(); +Terminal._colors = Terminal.colors.slice(); +Terminal.vcolors = (function () { + var out = [], colors = Terminal.colors, i = 0, color; + for (; i < 256; i++) { + color = parseInt(colors[i].substring(1), 16); + out.push([ + (color >> 16) & 0xff, + (color >> 8) & 0xff, + color & 0xff + ]); + } + return out; +})(); +Terminal.defaults = { + colors: Terminal.colors, + theme: 'default', + convertEol: false, + termName: 'xterm', + geometry: [80, 24], + cursorBlink: false, + cursorStyle: 'block', + visualBell: false, + popOnBell: false, + scrollback: 1000, + screenKeys: false, + debug: false, + cancelEvents: false, + disableStdin: false, + useFlowControl: false, + tabStopWidth: 8 +}; +Terminal.options = {}; +Terminal.focus = null; +each(keys(Terminal.defaults), function (key) { + Terminal[key] = Terminal.defaults[key]; + Terminal.options[key] = Terminal.defaults[key]; +}); +Terminal.prototype.focus = function () { + return this.textarea.focus(); +}; +Terminal.prototype.getOption = function (key, value) { + if (!(key in Terminal.defaults)) { + throw new Error('No option with key "' + key + '"'); + } + if (typeof this.options[key] !== 'undefined') { + return this.options[key]; + } + return this[key]; +}; +Terminal.prototype.setOption = function (key, value) { + if (!(key in Terminal.defaults)) { + throw new Error('No option with key "' + key + '"'); + } + switch (key) { + case 'scrollback': + if (this.options[key] !== value) { + if (this.lines.length > value) { + var amountToTrim = this.lines.length - value; + var needsRefresh = (this.ydisp - amountToTrim < 0); + this.lines.trimStart(amountToTrim); + this.ybase = Math.max(this.ybase - amountToTrim, 0); + this.ydisp = Math.max(this.ydisp - amountToTrim, 0); + if (needsRefresh) { + this.refresh(0, this.rows - 1); + } + } + this.lines.maxLength = value; + this.viewport.syncScrollArea(); + } + break; + } + this[key] = value; + this.options[key] = value; + switch (key) { + case 'cursorBlink': + this.element.classList.toggle('xterm-cursor-blink', value); + break; + case 'cursorStyle': + this.element.classList.toggle("xterm-cursor-style-underline", value === 'underline'); + this.element.classList.toggle("xterm-cursor-style-bar", value === 'bar'); + break; + case 'tabStopWidth': + this.setupStops(); + break; + } +}; +Terminal.bindFocus = function (term) { + on(term.textarea, 'focus', function (ev) { + if (term.sendFocus) { + term.send(EscapeSequences_1.C0.ESC + '[I'); + } + term.element.classList.add('focus'); + term.showCursor(); + Terminal.focus = term; + term.emit('focus', { terminal: term }); + }); +}; +Terminal.prototype.blur = function () { + return this.textarea.blur(); +}; +Terminal.bindBlur = function (term) { + on(term.textarea, 'blur', function (ev) { + term.refresh(term.y, term.y); + if (term.sendFocus) { + term.send(EscapeSequences_1.C0.ESC + '[O'); + } + term.element.classList.remove('focus'); + Terminal.focus = null; + term.emit('blur', { terminal: term }); + }); +}; +Terminal.prototype.initGlobal = function () { + var term = this; + Terminal.bindKeys(this); + Terminal.bindFocus(this); + Terminal.bindBlur(this); + on(this.element, 'copy', function (ev) { + Clipboard_1.copyHandler.call(this, ev, term); + }); + on(this.textarea, 'paste', function (ev) { + Clipboard_1.pasteHandler.call(this, ev, term); + }); + on(this.element, 'paste', function (ev) { + Clipboard_1.pasteHandler.call(this, ev, term); + }); + function rightClickHandlerWrapper(ev) { + Clipboard_1.rightClickHandler.call(this, ev, term); + } + if (term.browser.isFirefox) { + on(this.element, 'mousedown', function (ev) { + if (ev.button == 2) { + rightClickHandlerWrapper(ev); + } + }); + } + else { + on(this.element, 'contextmenu', rightClickHandlerWrapper); + } +}; +Terminal.bindKeys = function (term) { + on(term.element, 'keydown', function (ev) { + if (document.activeElement != this) { + return; + } + term.keyDown(ev); + }, true); + on(term.element, 'keypress', function (ev) { + if (document.activeElement != this) { + return; + } + term.keyPress(ev); + }, true); + on(term.element, 'keyup', function (ev) { + if (!wasMondifierKeyOnlyEvent(ev)) { + term.focus(term); + } + }, true); + on(term.textarea, 'keydown', function (ev) { + term.keyDown(ev); + }, true); + on(term.textarea, 'keypress', function (ev) { + term.keyPress(ev); + this.value = ''; + }, true); + on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper)); + on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper)); + on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper)); + term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper)); +}; +Terminal.prototype.insertRow = function (row) { + if (typeof row != 'object') { + row = document.createElement('div'); + } + this.rowContainer.appendChild(row); + this.children.push(row); + return row; +}; +Terminal.prototype.open = function (parent) { + var self = this, i = 0, div; + this.parent = parent || this.parent; + if (!this.parent) { + throw new Error('Terminal requires a parent element.'); + } + this.context = this.parent.ownerDocument.defaultView; + this.document = this.parent.ownerDocument; + this.body = this.document.getElementsByTagName('body')[0]; + this.element = this.document.createElement('div'); + this.element.classList.add('terminal'); + this.element.classList.add('xterm'); + this.element.classList.add('xterm-theme-' + this.theme); + this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink); + this.element.style.height; + this.element.setAttribute('tabindex', 0); + this.viewportElement = document.createElement('div'); + this.viewportElement.classList.add('xterm-viewport'); + this.element.appendChild(this.viewportElement); + this.viewportScrollArea = document.createElement('div'); + this.viewportScrollArea.classList.add('xterm-scroll-area'); + this.viewportElement.appendChild(this.viewportScrollArea); + this.rowContainer = document.createElement('div'); + this.rowContainer.classList.add('xterm-rows'); + this.element.appendChild(this.rowContainer); + this.children = []; + this.helperContainer = document.createElement('div'); + this.helperContainer.classList.add('xterm-helpers'); + this.element.appendChild(this.helperContainer); + this.textarea = document.createElement('textarea'); + this.textarea.classList.add('xterm-helper-textarea'); + this.textarea.setAttribute('autocorrect', 'off'); + this.textarea.setAttribute('autocapitalize', 'off'); + this.textarea.setAttribute('spellcheck', 'false'); + this.textarea.tabIndex = 0; + this.textarea.addEventListener('focus', function () { + self.emit('focus', { terminal: self }); + }); + this.textarea.addEventListener('blur', function () { + self.emit('blur', { terminal: self }); + }); + this.helperContainer.appendChild(this.textarea); + this.compositionView = document.createElement('div'); + this.compositionView.classList.add('composition-view'); + this.compositionHelper = new CompositionHelper_1.CompositionHelper(this.textarea, this.compositionView, this); + this.helperContainer.appendChild(this.compositionView); + this.charSizeStyleElement = document.createElement('style'); + this.helperContainer.appendChild(this.charSizeStyleElement); + for (; i < this.rows; i++) { + this.insertRow(); + } + this.parent.appendChild(this.element); + this.charMeasure = new CharMeasure_1.CharMeasure(this.helperContainer); + this.charMeasure.on('charsizechanged', function () { + self.updateCharSizeCSS(); + }); + this.charMeasure.measure(); + this.viewport = new Viewport_1.Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); + this.renderer = new Renderer_1.Renderer(this); + this.refresh(0, this.rows - 1); + this.initGlobal(); + this.focus(); + on(this.element, 'click', function () { + var selection = document.getSelection(), collapsed = selection.isCollapsed, isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range'; + if (!isRange) { + self.focus(); + } + }); + this.bindMouse(); + this.emit('open'); +}; +Terminal.loadAddon = function (addon, callback) { + if (typeof exports === 'object' && typeof module === 'object') { + return require('./addons/' + addon + '/' + addon); + } + else if (typeof define == 'function') { + return require(['./addons/' + addon + '/' + addon], callback); + } + else { + console.error('Cannot load a module without a CommonJS or RequireJS environment.'); + return false; + } +}; +Terminal.prototype.updateCharSizeCSS = function () { + this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}'; +}; +Terminal.prototype.bindMouse = function () { + var el = this.element, self = this, pressed = 32; + function sendButton(ev) { + var button, pos; + button = getButton(ev); + pos = getCoords(ev); + if (!pos) + return; + sendEvent(button, pos); + switch (ev.overrideType || ev.type) { + case 'mousedown': + pressed = button; + break; + case 'mouseup': + pressed = 32; + break; + case 'wheel': + break; + } + } + function sendMove(ev) { + var button = pressed, pos; + pos = getCoords(ev); + if (!pos) + return; + button += 32; + sendEvent(button, pos); + } + function encode(data, ch) { + if (!self.utfMouse) { + if (ch === 255) + return data.push(0); + if (ch > 127) + ch = 127; + data.push(ch); + } + else { + if (ch === 2047) + return data.push(0); + if (ch < 127) { + data.push(ch); + } + else { + if (ch > 2047) + ch = 2047; + data.push(0xC0 | (ch >> 6)); + data.push(0x80 | (ch & 0x3F)); + } + } + } + function sendEvent(button, pos) { + if (self.vt300Mouse) { + button &= 3; + pos.x -= 32; + pos.y -= 32; + var data = EscapeSequences_1.C0.ESC + '[24'; + if (button === 0) + data += '1'; + else if (button === 1) + data += '3'; + else if (button === 2) + data += '5'; + else if (button === 3) + return; + else + data += '0'; + data += '~[' + pos.x + ',' + pos.y + ']\r'; + self.send(data); + return; + } + if (self.decLocator) { + button &= 3; + pos.x -= 32; + pos.y -= 32; + if (button === 0) + button = 2; + else if (button === 1) + button = 4; + else if (button === 2) + button = 6; + else if (button === 3) + button = 3; + self.send(EscapeSequences_1.C0.ESC + '[' + + button + + ';' + + (button === 3 ? 4 : 0) + + ';' + + pos.y + + ';' + + pos.x + + ';' + + (pos.page || 0) + + '&w'); + return; + } + if (self.urxvtMouse) { + pos.x -= 32; + pos.y -= 32; + pos.x++; + pos.y++; + self.send(EscapeSequences_1.C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M'); + return; + } + if (self.sgrMouse) { + pos.x -= 32; + pos.y -= 32; + self.send(EscapeSequences_1.C0.ESC + '[<' + + (((button & 3) === 3 ? button & ~3 : button) - 32) + + ';' + + pos.x + + ';' + + pos.y + + ((button & 3) === 3 ? 'm' : 'M')); + return; + } + var data = []; + encode(data, button); + encode(data, pos.x); + encode(data, pos.y); + self.send(EscapeSequences_1.C0.ESC + '[M' + String.fromCharCode.apply(String, data)); + } + function getButton(ev) { + var button, shift, meta, ctrl, mod; + switch (ev.overrideType || ev.type) { + case 'mousedown': + button = ev.button != null + ? +ev.button + : ev.which != null + ? ev.which - 1 + : null; + if (self.browser.isMSIE) { + button = button === 1 ? 0 : button === 4 ? 1 : button; + } + break; + case 'mouseup': + button = 3; + break; + case 'DOMMouseScroll': + button = ev.detail < 0 + ? 64 + : 65; + break; + case 'wheel': + button = ev.wheelDeltaY > 0 + ? 64 + : 65; + break; + } + shift = ev.shiftKey ? 4 : 0; + meta = ev.metaKey ? 8 : 0; + ctrl = ev.ctrlKey ? 16 : 0; + mod = shift | meta | ctrl; + if (self.vt200Mouse) { + mod &= ctrl; + } + else if (!self.normalMouse) { + mod = 0; + } + button = (32 + (mod << 2)) + button; + return button; + } + function getCoords(ev) { + var x, y, w, h, el; + if (ev.pageX == null) + return; + x = ev.pageX; + y = ev.pageY; + el = self.element; + while (el && el !== self.document.documentElement) { + x -= el.offsetLeft; + y -= el.offsetTop; + el = 'offsetParent' in el + ? el.offsetParent + : el.parentNode; + } + w = self.element.clientWidth; + h = self.element.clientHeight; + x = Math.ceil((x / w) * self.cols); + y = Math.ceil((y / h) * self.rows); + if (x < 0) + x = 0; + if (x > self.cols) + x = self.cols; + if (y < 0) + y = 0; + if (y > self.rows) + y = self.rows; + x += 32; + y += 32; + return { + x: x, + y: y, + type: 'wheel' + }; + } + on(el, 'mousedown', function (ev) { + if (!self.mouseEvents) + return; + sendButton(ev); + self.focus(); + if (self.vt200Mouse) { + ev.overrideType = 'mouseup'; + sendButton(ev); + return self.cancel(ev); + } + if (self.normalMouse) + on(self.document, 'mousemove', sendMove); + if (!self.x10Mouse) { + on(self.document, 'mouseup', function up(ev) { + sendButton(ev); + if (self.normalMouse) + off(self.document, 'mousemove', sendMove); + off(self.document, 'mouseup', up); + return self.cancel(ev); + }); + } + return self.cancel(ev); + }); + on(el, 'wheel', function (ev) { + if (!self.mouseEvents) + return; + if (self.x10Mouse + || self.vt300Mouse + || self.decLocator) + return; + sendButton(ev); + return self.cancel(ev); + }); + on(el, 'wheel', function (ev) { + if (self.mouseEvents) + return; + self.viewport.onWheel(ev); + return self.cancel(ev); + }); +}; +Terminal.prototype.destroy = function () { + this.readable = false; + this.writable = false; + this._events = {}; + this.handler = function () { }; + this.write = function () { }; + if (this.element && this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + } +}; +Terminal.prototype.refresh = function (start, end) { + if (this.renderer) { + this.renderer.queueRefresh(start, end); + } +}; +Terminal.prototype.showCursor = function () { + if (!this.cursorState) { + this.cursorState = 1; + this.refresh(this.y, this.y); + } +}; +Terminal.prototype.scroll = function () { + var row; + if (this.lines.length === this.lines.maxLength) { + this.lines.trimStart(1); + this.ybase--; + if (this.ydisp !== 0) { + this.ydisp--; + } + } + this.ybase++; + if (!this.userScrolling) { + this.ydisp = this.ybase; + } + row = this.ybase + this.rows - 1; + row -= this.rows - 1 - this.scrollBottom; + if (row === this.lines.length) { + this.lines.push(this.blankLine()); + } + else { + this.lines.splice(row, 0, this.blankLine()); + } + if (this.scrollTop !== 0) { + if (this.ybase !== 0) { + this.ybase--; + if (!this.userScrolling) { + this.ydisp = this.ybase; + } + } + this.lines.splice(this.ybase + this.scrollTop, 1); + } + this.updateRange(this.scrollTop); + this.updateRange(this.scrollBottom); + this.emit('scroll', this.ydisp); +}; +Terminal.prototype.scrollDisp = function (disp, suppressScrollEvent) { + if (disp < 0) { + this.userScrolling = true; + } + else if (disp + this.ydisp >= this.ybase) { + this.userScrolling = false; + } + this.ydisp += disp; + if (this.ydisp > this.ybase) { + this.ydisp = this.ybase; + } + else if (this.ydisp < 0) { + this.ydisp = 0; + } + if (!suppressScrollEvent) { + this.emit('scroll', this.ydisp); + } + this.refresh(0, this.rows - 1); +}; +Terminal.prototype.scrollPages = function (pageCount) { + this.scrollDisp(pageCount * (this.rows - 1)); +}; +Terminal.prototype.scrollToTop = function () { + this.scrollDisp(-this.ydisp); +}; +Terminal.prototype.scrollToBottom = function () { + this.scrollDisp(this.ybase - this.ydisp); +}; +Terminal.prototype.write = function (data) { + this.writeBuffer.push(data); + if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { + this.send(EscapeSequences_1.C0.DC3); + this.xoffSentToCatchUp = true; + } + if (!this.writeInProgress && this.writeBuffer.length > 0) { + this.writeInProgress = true; + var self = this; + setTimeout(function () { + self.innerWrite(); + }); + } +}; +Terminal.prototype.innerWrite = function () { + var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); + while (writeBatch.length > 0) { + var data = writeBatch.shift(); + var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; + if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) { + this.send(EscapeSequences_1.C0.DC1); + this.xoffSentToCatchUp = false; + } + this.refreshStart = this.y; + this.refreshEnd = this.y; + this.parser.parse(data); + this.updateRange(this.y); + this.refresh(this.refreshStart, this.refreshEnd); + } + if (this.writeBuffer.length > 0) { + var self = this; + setTimeout(function () { + self.innerWrite(); + }, 0); + } + else { + this.writeInProgress = false; + } +}; +Terminal.prototype.writeln = function (data) { + this.write(data + '\r\n'); +}; +Terminal.prototype.attachCustomKeydownHandler = function (customKeydownHandler) { + this.customKeydownHandler = customKeydownHandler; +}; +Terminal.prototype.keyDown = function (ev) { + if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) { + return false; + } + if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { + if (this.ybase !== this.ydisp) { + this.scrollToBottom(); + } + return false; + } + var self = this; + var result = this.evaluateKeyEscapeSequence(ev); + if (result.key === EscapeSequences_1.C0.DC3) { + this.writeStopped = true; + } + else if (result.key === EscapeSequences_1.C0.DC1) { + this.writeStopped = false; + } + if (result.scrollDisp) { + this.scrollDisp(result.scrollDisp); + return this.cancel(ev, true); + } + if (isThirdLevelShift(this, ev)) { + return true; + } + if (result.cancel) { + this.cancel(ev, true); + } + if (!result.key) { + return true; + } + this.emit('keydown', ev); + this.emit('key', result.key, ev); + this.showCursor(); + this.handler(result.key); + return this.cancel(ev, true); +}; +Terminal.prototype.evaluateKeyEscapeSequence = function (ev) { + var result = { + cancel: false, + key: undefined, + scrollDisp: undefined + }; + var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3; + switch (ev.keyCode) { + case 8: + if (ev.shiftKey) { + result.key = EscapeSequences_1.C0.BS; + break; + } + result.key = EscapeSequences_1.C0.DEL; + break; + case 9: + if (ev.shiftKey) { + result.key = EscapeSequences_1.C0.ESC + '[Z'; + break; + } + result.key = EscapeSequences_1.C0.HT; + result.cancel = true; + break; + case 13: + result.key = EscapeSequences_1.C0.CR; + result.cancel = true; + break; + case 27: + result.key = EscapeSequences_1.C0.ESC; + result.cancel = true; + break; + case 37: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'D'; + if (result.key == EscapeSequences_1.C0.ESC + '[1;3D') { + result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'b' : EscapeSequences_1.C0.ESC + '[1;5D'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OD'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[D'; + } + break; + case 39: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'C'; + if (result.key == EscapeSequences_1.C0.ESC + '[1;3C') { + result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'f' : EscapeSequences_1.C0.ESC + '[1;5C'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OC'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[C'; + } + break; + case 38: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'A'; + if (result.key == EscapeSequences_1.C0.ESC + '[1;3A') { + result.key = EscapeSequences_1.C0.ESC + '[1;5A'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OA'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[A'; + } + break; + case 40: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'B'; + if (result.key == EscapeSequences_1.C0.ESC + '[1;3B') { + result.key = EscapeSequences_1.C0.ESC + '[1;5B'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OB'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[B'; + } + break; + case 45: + if (!ev.shiftKey && !ev.ctrlKey) { + result.key = EscapeSequences_1.C0.ESC + '[2~'; + } + break; + case 46: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[3;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[3~'; + } + break; + case 36: + if (modifiers) + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'H'; + else if (this.applicationCursor) + result.key = EscapeSequences_1.C0.ESC + 'OH'; + else + result.key = EscapeSequences_1.C0.ESC + '[H'; + break; + case 35: + if (modifiers) + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'F'; + else if (this.applicationCursor) + result.key = EscapeSequences_1.C0.ESC + 'OF'; + else + result.key = EscapeSequences_1.C0.ESC + '[F'; + break; + case 33: + if (ev.shiftKey) { + result.scrollDisp = -(this.rows - 1); + } + else { + result.key = EscapeSequences_1.C0.ESC + '[5~'; + } + break; + case 34: + if (ev.shiftKey) { + result.scrollDisp = this.rows - 1; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[6~'; + } + break; + case 112: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'P'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OP'; + } + break; + case 113: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'Q'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OQ'; + } + break; + case 114: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'R'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OR'; + } + break; + case 115: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'S'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OS'; + } + break; + case 116: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[15;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[15~'; + } + break; + case 117: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[17;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[17~'; + } + break; + case 118: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[18;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[18~'; + } + break; + case 119: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[19;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[19~'; + } + break; + case 120: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[20;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[20~'; + } + break; + case 121: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[21;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[21~'; + } + break; + case 122: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[23;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[23~'; + } + break; + case 123: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[24;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[24~'; + } + break; + default: + if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = String.fromCharCode(ev.keyCode - 64); + } + else if (ev.keyCode === 32) { + result.key = String.fromCharCode(0); + } + else if (ev.keyCode >= 51 && ev.keyCode <= 55) { + result.key = String.fromCharCode(ev.keyCode - 51 + 27); + } + else if (ev.keyCode === 56) { + result.key = String.fromCharCode(127); + } + else if (ev.keyCode === 219) { + result.key = String.fromCharCode(27); + } + else if (ev.keyCode === 220) { + result.key = String.fromCharCode(28); + } + else if (ev.keyCode === 221) { + result.key = String.fromCharCode(29); + } + } + else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = EscapeSequences_1.C0.ESC + String.fromCharCode(ev.keyCode + 32); + } + else if (ev.keyCode === 192) { + result.key = EscapeSequences_1.C0.ESC + '`'; + } + else if (ev.keyCode >= 48 && ev.keyCode <= 57) { + result.key = EscapeSequences_1.C0.ESC + (ev.keyCode - 48); + } + } + break; + } + return result; +}; +Terminal.prototype.setgLevel = function (g) { + this.glevel = g; + this.charset = this.charsets[g]; +}; +Terminal.prototype.setgCharset = function (g, charset) { + this.charsets[g] = charset; + if (this.glevel === g) { + this.charset = charset; + } +}; +Terminal.prototype.keyPress = function (ev) { + var key; + this.cancel(ev); + if (ev.charCode) { + key = ev.charCode; + } + else if (ev.which == null) { + key = ev.keyCode; + } + else if (ev.which !== 0 && ev.charCode !== 0) { + key = ev.which; + } + else { + return false; + } + if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev))) { + return false; + } + key = String.fromCharCode(key); + this.emit('keypress', key, ev); + this.emit('key', key, ev); + this.showCursor(); + this.handler(key); + return false; +}; +Terminal.prototype.send = function (data) { + var self = this; + if (!this.queue) { + setTimeout(function () { + self.handler(self.queue); + self.queue = ''; + }, 1); + } + this.queue += data; +}; +Terminal.prototype.bell = function () { + if (!this.visualBell) + return; + var self = this; + this.element.style.borderColor = 'white'; + setTimeout(function () { + self.element.style.borderColor = ''; + }, 10); + if (this.popOnBell) + this.focus(); +}; +Terminal.prototype.log = function () { + if (!this.debug) + return; + if (!this.context.console || !this.context.console.log) + return; + var args = Array.prototype.slice.call(arguments); + this.context.console.log.apply(this.context.console, args); +}; +Terminal.prototype.error = function () { + if (!this.debug) + return; + if (!this.context.console || !this.context.console.error) + return; + var args = Array.prototype.slice.call(arguments); + this.context.console.error.apply(this.context.console, args); +}; +Terminal.prototype.resize = function (x, y) { + if (Number.isNaN(x) || Number.isNaN(y)) { + return; + } + var line, el, i, j, ch, addToY; + if (x === this.cols && y === this.rows) { + return; + } + if (x < 1) + x = 1; + if (y < 1) + y = 1; + j = this.cols; + if (j < x) { + ch = [this.defAttr, ' ', 1]; + i = this.lines.length; + while (i--) { + while (this.lines.get(i).length < x) { + this.lines.get(i).push(ch); + } + } + } + else { + i = this.lines.length; + while (i--) { + while (this.lines.get(i).length > x) { + this.lines.get(i).pop(); + } + } + } + this.cols = x; + this.setupStops(this.cols); + j = this.rows; + addToY = 0; + if (j < y) { + el = this.element; + while (j++ < y) { + if (this.lines.length < y + this.ybase) { + if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) { + this.ybase--; + addToY++; + if (this.ydisp > 0) { + this.ydisp--; + } + } + else { + this.lines.push(this.blankLine()); + } + } + if (this.children.length < y) { + this.insertRow(); + } + } + } + else { + while (j-- > y) { + if (this.lines.length > y + this.ybase) { + if (this.lines.length > this.ybase + this.y + 1) { + this.lines.pop(); + } + else { + this.ybase++; + this.ydisp++; + } + } + if (this.children.length > y) { + el = this.children.shift(); + if (!el) + continue; + el.parentNode.removeChild(el); + } + } + } + this.rows = y; + if (this.y >= y) { + this.y = y - 1; + } + if (addToY) { + this.y += addToY; + } + if (this.x >= x) { + this.x = x - 1; + } + this.scrollTop = 0; + this.scrollBottom = y - 1; + this.charMeasure.measure(); + this.refresh(0, this.rows - 1); + this.normal = null; + this.geometry = [this.cols, this.rows]; + this.emit('resize', { terminal: this, cols: x, rows: y }); +}; +Terminal.prototype.updateRange = function (y) { + if (y < this.refreshStart) + this.refreshStart = y; + if (y > this.refreshEnd) + this.refreshEnd = y; +}; +Terminal.prototype.maxRange = function () { + this.refreshStart = 0; + this.refreshEnd = this.rows - 1; +}; +Terminal.prototype.setupStops = function (i) { + if (i != null) { + if (!this.tabs[i]) { + i = this.prevStop(i); + } + } + else { + this.tabs = {}; + i = 0; + } + for (; i < this.cols; i += this.getOption('tabStopWidth')) { + this.tabs[i] = true; + } +}; +Terminal.prototype.prevStop = function (x) { + if (x == null) + x = this.x; + while (!this.tabs[--x] && x > 0) + ; + return x >= this.cols + ? this.cols - 1 + : x < 0 ? 0 : x; +}; +Terminal.prototype.nextStop = function (x) { + if (x == null) + x = this.x; + while (!this.tabs[++x] && x < this.cols) + ; + return x >= this.cols + ? this.cols - 1 + : x < 0 ? 0 : x; +}; +Terminal.prototype.eraseRight = function (x, y) { + var line = this.lines.get(this.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1]; + for (; x < this.cols; x++) { + line[x] = ch; + } + this.updateRange(y); +}; +Terminal.prototype.eraseLeft = function (x, y) { + var line = this.lines.get(this.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1]; + x++; + while (x--) { + line[x] = ch; + } + this.updateRange(y); +}; +Terminal.prototype.clear = function () { + if (this.ybase === 0 && this.y === 0) { + return; + } + this.lines.set(0, this.lines.get(this.ybase + this.y)); + this.lines.length = 1; + this.ydisp = 0; + this.ybase = 0; + this.y = 0; + for (var i = 1; i < this.rows; i++) { + this.lines.push(this.blankLine()); + } + this.refresh(0, this.rows - 1); + this.emit('scroll', this.ydisp); +}; +Terminal.prototype.eraseLine = function (y) { + this.eraseRight(0, y); +}; +Terminal.prototype.blankLine = function (cur) { + var attr = cur + ? this.eraseAttr() + : this.defAttr; + var ch = [attr, ' ', 1], line = [], i = 0; + for (; i < this.cols; i++) { + line[i] = ch; + } + return line; +}; +Terminal.prototype.ch = function (cur) { + return cur + ? [this.eraseAttr(), ' ', 1] + : [this.defAttr, ' ', 1]; +}; +Terminal.prototype.is = function (term) { + var name = this.termName; + return (name + '').indexOf(term) === 0; +}; +Terminal.prototype.handler = function (data) { + if (this.options.disableStdin) { + return; + } + if (this.ybase !== this.ydisp) { + this.scrollToBottom(); + } + this.emit('data', data); +}; +Terminal.prototype.handleTitle = function (title) { + this.emit('title', title); +}; +Terminal.prototype.index = function () { + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } + if (this.x >= this.cols) { + this.x--; + } +}; +Terminal.prototype.reverseIndex = function () { + var j; + if (this.y === this.scrollTop) { + this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1); + this.lines.set(this.y + this.ybase, this.blankLine(true)); + this.updateRange(this.scrollTop); + this.updateRange(this.scrollBottom); + } + else { + this.y--; + } +}; +Terminal.prototype.reset = function () { + this.options.rows = this.rows; + this.options.cols = this.cols; + var customKeydownHandler = this.customKeydownHandler; + Terminal.call(this, this.options); + this.customKeydownHandler = customKeydownHandler; + this.refresh(0, this.rows - 1); + this.viewport.syncScrollArea(); +}; +Terminal.prototype.tabSet = function () { + this.tabs[this.x] = true; +}; +function on(el, type, handler, capture) { + if (!Array.isArray(el)) { + el = [el]; + } + el.forEach(function (element) { + element.addEventListener(type, handler, capture || false); + }); +} +function off(el, type, handler, capture) { + el.removeEventListener(type, handler, capture || false); +} +function cancel(ev, force) { + if (!this.cancelEvents && !force) { + return; + } + ev.preventDefault(); + ev.stopPropagation(); + return false; +} +function inherits(child, parent) { + function f() { + this.constructor = child; + } + f.prototype = parent.prototype; + child.prototype = new f; +} +function indexOf(obj, el) { + var i = obj.length; + while (i--) { + if (obj[i] === el) + return i; + } + return -1; +} +function isThirdLevelShift(term, ev) { + var thirdLevelKey = (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || + (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); + if (ev.type == 'keypress') { + return thirdLevelKey; + } + return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); +} +Terminal.prototype.matchColor = matchColor; +function matchColor(r1, g1, b1) { + var hash = (r1 << 16) | (g1 << 8) | b1; + if (matchColor._cache[hash] != null) { + return matchColor._cache[hash]; + } + var ldiff = Infinity, li = -1, i = 0, c, r2, g2, b2, diff; + for (; i < Terminal.vcolors.length; i++) { + c = Terminal.vcolors[i]; + r2 = c[0]; + g2 = c[1]; + b2 = c[2]; + diff = matchColor.distance(r1, g1, b1, r2, g2, b2); + if (diff === 0) { + li = i; + break; + } + if (diff < ldiff) { + ldiff = diff; + li = i; + } + } + return matchColor._cache[hash] = li; +} +matchColor._cache = {}; +matchColor.distance = function (r1, g1, b1, r2, g2, b2) { + return Math.pow(30 * (r1 - r2), 2) + + Math.pow(59 * (g1 - g2), 2) + + Math.pow(11 * (b1 - b2), 2); +}; +function each(obj, iter, con) { + if (obj.forEach) + return obj.forEach(iter, con); + for (var i = 0; i < obj.length; i++) { + iter.call(con, obj[i], i, obj); + } +} +function wasMondifierKeyOnlyEvent(ev) { + return ev.keyCode === 16 || + ev.keyCode === 17 || + ev.keyCode === 18; +} +function keys(obj) { + if (Object.keys) + return Object.keys(obj); + var key, keys = []; + for (key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + keys.push(key); + } + } + return keys; +} +Terminal.EventEmitter = EventEmitter_1.EventEmitter; Terminal.inherits = inherits; -/** - * Adds an event listener to the terminal. - * - * @param {string} event The name of the event. TODO: Document all event types - * @param {function} callback The function to call when the event is triggered. - */ Terminal.on = on; Terminal.off = off; Terminal.cancel = cancel; module.exports = Terminal; -},{"./CompositionHelper.js":1,"./EventEmitter.js":2,"./Viewport.js":3,"./handlers/Clipboard.js":4,"./utils/Browser":5}]},{},[7])(7) +},{"./CompositionHelper":2,"./EscapeSequences":3,"./EventEmitter":4,"./InputHandler":5,"./Parser":6,"./Renderer":7,"./Viewport":8,"./handlers/Clipboard":9,"./utils/Browser":10,"./utils/CharMeasure":11,"./utils/CircularList":12}]},{},[14])(14) }); //# sourceMappingURL=xterm.js.map diff --git a/dist/xterm.js.map b/dist/xterm.js.map index 947a5869..5fe7bf06 100644 --- a/dist/xterm.js.map +++ b/dist/xterm.js.map @@ -1 +1 @@ -{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.js","../src/utils/Browser.js","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/EventEmitter.js","../src/CompositionHelper.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper.js';\nimport { EventEmitter } from './EventEmitter.js';\nimport { Viewport } from './Viewport.js';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * States\n */\nvar normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n /**\n * Used to debounce the refresh function\n */\n this.isRefreshing = false;\n\n /**\n * Whether there is a full terminal refresh queued\n */\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.state = 0;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = [];\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n this[key] = value;\n this.options[key] = value;\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send('\\x1b[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send('\\x1b[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', term.focus.bind(term));\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charMeasureElement = document.createElement('div');\n this.charMeasureElement.classList.add('xterm-char-measure-element');\n this.charMeasureElement.innerHTML = 'W';\n this.helperContainer.appendChild(this.charMeasureElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasureElement);\n\n // Draw the screen.\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (Terminal.brokenBold == null) {\n Terminal.brokenBold = isBoldBroken(this.document);\n }\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = '\\x1b[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send('\\x1b['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send('\\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send('\\x1b[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send('\\x1b[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n\n/**\n * Flags used to render terminal text properly\n */\nTerminal.flags = {\n BOLD: 1,\n UNDERLINE: 2,\n BLINK: 4,\n INVERSE: 8,\n INVISIBLE: 16\n}\n\n/**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n * @param {boolean} queue Whether the refresh should ran right now or be queued\n */\nTerminal.prototype.refresh = function(start, end, queue) {\n var self = this;\n\n // queue defaults to true\n queue = (typeof queue == 'undefined') ? true : queue;\n\n /**\n * The refresh queue allows refresh to execute only approximately 30 times a second. For\n * commands that pass a significant amount of output to the write function, this prevents the\n * terminal from maxing out the CPU and making the UI unresponsive. While commands can still\n * run beyond what they do on the terminal, it is far better with a debounce in place as\n * every single terminal manipulation does not need to be constructed in the DOM.\n *\n * A side-effect of this is that it makes ^C to interrupt a process seem more responsive.\n */\n if (queue) {\n // If refresh should be queued, order the refresh and return.\n if (this._refreshIsQueued) {\n // If a refresh has already been queued, just order a full refresh next\n this._fullRefreshNext = true;\n } else {\n setTimeout(function () {\n self.refresh(start, end, false);\n }, 34)\n this._refreshIsQueued = true;\n }\n return;\n }\n\n // If refresh should be run right now (not be queued), release the lock\n this._refreshIsQueued = false;\n\n // If multiple refreshes were requested, make a full refresh.\n if (this._fullRefreshNext) {\n start = 0;\n end = this.rows - 1;\n this._fullRefreshNext = false // reset lock\n }\n\n var x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this.rows / 2) {\n parent = this.element.parentNode;\n if (parent) {\n this.element.removeChild(this.rowContainer);\n }\n }\n\n width = this.cols;\n y = start;\n\n if (end >= this.rows.length) {\n this.log('`end` is too large. Most likely a bad CSR.');\n end = this.rows.length - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this.ydisp;\n\n line = this.lines[row];\n out = '';\n\n if (this.y === y - (this.ybase - this.ydisp)\n && this.cursorState\n && !this.cursorHidden) {\n x = this.x;\n } else {\n x = -1;\n }\n\n attr = this.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this.defAttr) {\n out += '';\n }\n if (data !== this.defAttr) {\n if (data === -1) {\n out += '> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & Terminal.flags.BOLD) {\n if (!Terminal.brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & Terminal.flags.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & Terminal.flags.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & Terminal.flags.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & Terminal.flags.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & Terminal.flags.INVERSE) {\n if (bg == 257) {\n bg = 15;\n }\n if (fg == 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n\n attr = data;\n }\n\n if (attr !== this.defAttr) {\n out += '';\n }\n\n this.children[y].innerHTML = out;\n }\n\n if (parent) {\n this.element.appendChild(this.rowContainer);\n }\n\n this.emit('refresh', {element: this.element, start: start, end: end});\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n if (++this.ybase === this.scrollback) {\n this.ybase = this.ybase / 2 | 0;\n this.lines = this.lines.slice(-(this.ybase + this.rows) + 1);\n }\n\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // potential optimization:\n // pushing is faster than splicing\n // when they amount to the same\n // behavior.\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n // apply leftover surrogate high from last write\n if (this.surrogate_high) {\n data = this.surrogate_high + data;\n this.surrogate_high = '';\n }\n\n for (; i < l; i++) {\n ch = data[i];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(i);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(i+1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(i+1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this.state) {\n case normal:\n switch (ch) {\n case '\\x07':\n this.bell();\n break;\n\n // '\\n', '\\v', '\\f'\n case '\\n':\n case '\\x0b':\n case '\\x0c':\n if (this.convertEol) {\n this.x = 0;\n }\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n break;\n\n // '\\r'\n case '\\r':\n this.x = 0;\n break;\n\n // '\\b'\n case '\\x08':\n if (this.x > 0) {\n this.x--;\n }\n break;\n\n // '\\t'\n case '\\t':\n this.x = this.nextStop();\n break;\n\n // shift out\n case '\\x0e':\n this.setgLevel(1);\n break;\n\n // shift in\n case '\\x0f':\n this.setgLevel(0);\n break;\n\n // '\\e'\n case '\\x1b':\n this.state = escaped;\n break;\n\n default:\n // ' '\n // calculate print space\n // expensive call, therefore we save width in line buffer\n ch_width = wcwidth(code);\n\n if (ch >= ' ') {\n if (this.charset && this.charset[ch]) {\n ch = this.charset[ch];\n }\n\n row = this.y + this.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this.x) {\n\n // dont overflow left\n if (this.lines[row][this.x-1]) {\n if (!this.lines[row][this.x-1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this.lines[row][this.x-2])\n this.lines[row][this.x-2][1] += ch;\n\n } else {\n this.lines[row][this.x-1][1] += ch;\n }\n this.updateRange(this.y);\n }\n break;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this.x+ch_width-1 >= this.cols) {\n // autowrap - DECAWM\n if (this.wraparoundMode) {\n this.x = 0;\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n } else {\n this.x = this.cols-1;\n if(ch_width===2) // FIXME: check for xterm behavior\n continue;\n }\n }\n row = this.y + this.ybase;\n\n // insert mode: move characters to right\n if (this.insertMode) {\n // do this twice for a fullwidth char\n for (var moves=0; moves Normal Keypad (DECKPNM).\n case '>':\n this.log('Switching back to normal keypad.');\n this.applicationKeypad = false;\n this.viewport.syncScrollArea();\n this.state = normal;\n break;\n\n default:\n this.state = normal;\n this.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case charset:\n switch (ch) {\n case '0': // DEC Special Character and Line Drawing Set.\n cs = Terminal.charsets.SCLD;\n break;\n case 'A': // UK\n cs = Terminal.charsets.UK;\n break;\n case 'B': // United States (USASCII).\n cs = Terminal.charsets.US;\n break;\n case '4': // Dutch\n cs = Terminal.charsets.Dutch;\n break;\n case 'C': // Finnish\n case '5':\n cs = Terminal.charsets.Finnish;\n break;\n case 'R': // French\n cs = Terminal.charsets.French;\n break;\n case 'Q': // FrenchCanadian\n cs = Terminal.charsets.FrenchCanadian;\n break;\n case 'K': // German\n cs = Terminal.charsets.German;\n break;\n case 'Y': // Italian\n cs = Terminal.charsets.Italian;\n break;\n case 'E': // NorwegianDanish\n case '6':\n cs = Terminal.charsets.NorwegianDanish;\n break;\n case 'Z': // Spanish\n cs = Terminal.charsets.Spanish;\n break;\n case 'H': // Swedish\n case '7':\n cs = Terminal.charsets.Swedish;\n break;\n case '=': // Swiss\n cs = Terminal.charsets.Swiss;\n break;\n case '/': // ISOLatin (actually /A)\n cs = Terminal.charsets.ISOLatin;\n i++;\n break;\n default: // Default\n cs = Terminal.charsets.US;\n break;\n }\n this.setgCharset(this.gcharset, cs);\n this.gcharset = null;\n this.state = normal;\n break;\n\n case osc:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === '\\x1b' || ch === '\\x07') {\n if (ch === '\\x1b') i++;\n\n this.params.push(this.currentParam);\n\n switch (this.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this.params[1]) {\n this.title = this.params[1];\n this.handleTitle(this.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this.params = [];\n this.currentParam = 0;\n this.state = normal;\n } else {\n if (!this.params.length) {\n if (ch >= '0' && ch <= '9') {\n this.currentParam =\n this.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this.params.push(this.currentParam);\n this.currentParam = '';\n }\n } else {\n this.currentParam += ch;\n }\n }\n break;\n\n case csi:\n // '?', '>', '!'\n if (ch === '?' || ch === '>' || ch === '!') {\n this.prefix = ch;\n break;\n }\n\n // 0 - 9\n if (ch >= '0' && ch <= '9') {\n this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48;\n break;\n }\n\n // '$', '\"', ' ', '\\''\n if (ch === '$' || ch === '\"' || ch === ' ' || ch === '\\'') {\n this.postfix = ch;\n break;\n }\n\n this.params.push(this.currentParam);\n this.currentParam = 0;\n\n // ';'\n if (ch === ';') break;\n\n this.state = normal;\n\n switch (ch) {\n // CSI Ps A\n // Cursor Up Ps Times (default = 1) (CUU).\n case 'A':\n this.cursorUp(this.params);\n break;\n\n // CSI Ps B\n // Cursor Down Ps Times (default = 1) (CUD).\n case 'B':\n this.cursorDown(this.params);\n break;\n\n // CSI Ps C\n // Cursor Forward Ps Times (default = 1) (CUF).\n case 'C':\n this.cursorForward(this.params);\n break;\n\n // CSI Ps D\n // Cursor Backward Ps Times (default = 1) (CUB).\n case 'D':\n this.cursorBackward(this.params);\n break;\n\n // CSI Ps ; Ps H\n // Cursor Position [row;column] (default = [1,1]) (CUP).\n case 'H':\n this.cursorPos(this.params);\n break;\n\n // CSI Ps J Erase in Display (ED).\n case 'J':\n this.eraseInDisplay(this.params);\n break;\n\n // CSI Ps K Erase in Line (EL).\n case 'K':\n this.eraseInLine(this.params);\n break;\n\n // CSI Pm m Character Attributes (SGR).\n case 'm':\n if (!this.prefix) {\n this.charAttributes(this.params);\n }\n break;\n\n // CSI Ps n Device Status Report (DSR).\n case 'n':\n if (!this.prefix) {\n this.deviceStatus(this.params);\n }\n break;\n\n /**\n * Additions\n */\n\n // CSI Ps @\n // Insert Ps (Blank) Character(s) (default = 1) (ICH).\n case '@':\n this.insertChars(this.params);\n break;\n\n // CSI Ps E\n // Cursor Next Line Ps Times (default = 1) (CNL).\n case 'E':\n this.cursorNextLine(this.params);\n break;\n\n // CSI Ps F\n // Cursor Preceding Line Ps Times (default = 1) (CNL).\n case 'F':\n this.cursorPrecedingLine(this.params);\n break;\n\n // CSI Ps G\n // Cursor Character Absolute [column] (default = [row,1]) (CHA).\n case 'G':\n this.cursorCharAbsolute(this.params);\n break;\n\n // CSI Ps L\n // Insert Ps Line(s) (default = 1) (IL).\n case 'L':\n this.insertLines(this.params);\n break;\n\n // CSI Ps M\n // Delete Ps Line(s) (default = 1) (DL).\n case 'M':\n this.deleteLines(this.params);\n break;\n\n // CSI Ps P\n // Delete Ps Character(s) (default = 1) (DCH).\n case 'P':\n this.deleteChars(this.params);\n break;\n\n // CSI Ps X\n // Erase Ps Character(s) (default = 1) (ECH).\n case 'X':\n this.eraseChars(this.params);\n break;\n\n // CSI Pm ` Character Position Absolute\n // [column] (default = [row,1]) (HPA).\n case '`':\n this.charPosAbsolute(this.params);\n break;\n\n // 141 61 a * HPR -\n // Horizontal Position Relative\n case 'a':\n this.HPositionRelative(this.params);\n break;\n\n // CSI P s c\n // Send Device Attributes (Primary DA).\n // CSI > P s c\n // Send Device Attributes (Secondary DA)\n case 'c':\n this.sendDeviceAttributes(this.params);\n break;\n\n // CSI Pm d\n // Line Position Absolute [row] (default = [1,column]) (VPA).\n case 'd':\n this.linePosAbsolute(this.params);\n break;\n\n // 145 65 e * VPR - Vertical Position Relative\n case 'e':\n this.VPositionRelative(this.params);\n break;\n\n // CSI Ps ; Ps f\n // Horizontal and Vertical Position [row;column] (default =\n // [1,1]) (HVP).\n case 'f':\n this.HVPosition(this.params);\n break;\n\n // CSI Pm h Set Mode (SM).\n // CSI ? Pm h - mouse escape codes, cursor escape codes\n case 'h':\n this.setMode(this.params);\n break;\n\n // CSI Pm l Reset Mode (RM).\n // CSI ? Pm l\n case 'l':\n this.resetMode(this.params);\n break;\n\n // CSI Ps ; Ps r\n // Set Scrolling Region [top;bottom] (default = full size of win-\n // dow) (DECSTBM).\n // CSI ? Pm r\n case 'r':\n this.setScrollRegion(this.params);\n break;\n\n // CSI s\n // Save cursor (ANSI.SYS).\n case 's':\n this.saveCursor(this.params);\n break;\n\n // CSI u\n // Restore cursor (ANSI.SYS).\n case 'u':\n this.restoreCursor(this.params);\n break;\n\n /**\n * Lesser Used\n */\n\n // CSI Ps I\n // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n case 'I':\n this.cursorForwardTab(this.params);\n break;\n\n // CSI Ps S Scroll up Ps lines (default = 1) (SU).\n case 'S':\n this.scrollUp(this.params);\n break;\n\n // CSI Ps T Scroll down Ps lines (default = 1) (SD).\n // CSI Ps ; Ps ; Ps ; Ps ; Ps T\n // CSI > Ps; Ps T\n case 'T':\n // if (this.prefix === '>') {\n // this.resetTitleModes(this.params);\n // break;\n // }\n // if (this.params.length > 2) {\n // this.initMouseTracking(this.params);\n // break;\n // }\n if (this.params.length < 2 && !this.prefix) {\n this.scrollDown(this.params);\n }\n break;\n\n // CSI Ps Z\n // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n case 'Z':\n this.cursorBackwardTab(this.params);\n break;\n\n // CSI Ps b Repeat the preceding graphic character Ps times (REP).\n case 'b':\n this.repeatPrecedingCharacter(this.params);\n break;\n\n // CSI Ps g Tab Clear (TBC).\n case 'g':\n this.tabClear(this.params);\n break;\n\n // CSI Pm i Media Copy (MC).\n // CSI ? Pm i\n // case 'i':\n // this.mediaCopy(this.params);\n // break;\n\n // CSI Pm m Character Attributes (SGR).\n // CSI > Ps; Ps m\n // case 'm': // duplicate\n // if (this.prefix === '>') {\n // this.setResources(this.params);\n // } else {\n // this.charAttributes(this.params);\n // }\n // break;\n\n // CSI Ps n Device Status Report (DSR).\n // CSI > Ps n\n // case 'n': // duplicate\n // if (this.prefix === '>') {\n // this.disableModifiers(this.params);\n // } else {\n // this.deviceStatus(this.params);\n // }\n // break;\n\n // CSI > Ps p Set pointer mode.\n // CSI ! p Soft terminal reset (DECSTR).\n // CSI Ps$ p\n // Request ANSI mode (DECRQM).\n // CSI ? Ps$ p\n // Request DEC private mode (DECRQM).\n // CSI Ps ; Ps \" p\n case 'p':\n switch (this.prefix) {\n // case '>':\n // this.setPointerMode(this.params);\n // break;\n case '!':\n this.softReset(this.params);\n break;\n // case '?':\n // if (this.postfix === '$') {\n // this.requestPrivateMode(this.params);\n // }\n // break;\n // default:\n // if (this.postfix === '\"') {\n // this.setConformanceLevel(this.params);\n // } else if (this.postfix === '$') {\n // this.requestAnsiMode(this.params);\n // }\n // break;\n }\n break;\n\n // CSI Ps q Load LEDs (DECLL).\n // CSI Ps SP q\n // CSI Ps \" q\n // case 'q':\n // if (this.postfix === ' ') {\n // this.setCursorStyle(this.params);\n // break;\n // }\n // if (this.postfix === '\"') {\n // this.setCharProtectionAttr(this.params);\n // break;\n // }\n // this.loadLEDs(this.params);\n // break;\n\n // CSI Ps ; Ps r\n // Set Scrolling Region [top;bottom] (default = full size of win-\n // dow) (DECSTBM).\n // CSI ? Pm r\n // CSI Pt; Pl; Pb; Pr; Ps$ r\n // case 'r': // duplicate\n // if (this.prefix === '?') {\n // this.restorePrivateValues(this.params);\n // } else if (this.postfix === '$') {\n // this.setAttrInRectangle(this.params);\n // } else {\n // this.setScrollRegion(this.params);\n // }\n // break;\n\n // CSI s Save cursor (ANSI.SYS).\n // CSI ? Pm s\n // case 's': // duplicate\n // if (this.prefix === '?') {\n // this.savePrivateValues(this.params);\n // } else {\n // this.saveCursor(this.params);\n // }\n // break;\n\n // CSI Ps ; Ps ; Ps t\n // CSI Pt; Pl; Pb; Pr; Ps$ t\n // CSI > Ps; Ps t\n // CSI Ps SP t\n // case 't':\n // if (this.postfix === '$') {\n // this.reverseAttrInRectangle(this.params);\n // } else if (this.postfix === ' ') {\n // this.setWarningBellVolume(this.params);\n // } else {\n // if (this.prefix === '>') {\n // this.setTitleModeFeature(this.params);\n // } else {\n // this.manipulateWindow(this.params);\n // }\n // }\n // break;\n\n // CSI u Restore cursor (ANSI.SYS).\n // CSI Ps SP u\n // case 'u': // duplicate\n // if (this.postfix === ' ') {\n // this.setMarginBellVolume(this.params);\n // } else {\n // this.restoreCursor(this.params);\n // }\n // break;\n\n // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v\n // case 'v':\n // if (this.postfix === '$') {\n // this.copyRectagle(this.params);\n // }\n // break;\n\n // CSI Pt ; Pl ; Pb ; Pr ' w\n // case 'w':\n // if (this.postfix === '\\'') {\n // this.enableFilterRectangle(this.params);\n // }\n // break;\n\n // CSI Ps x Request Terminal Parameters (DECREQTPARM).\n // CSI Ps x Select Attribute Change Extent (DECSACE).\n // CSI Pc; Pt; Pl; Pb; Pr$ x\n // case 'x':\n // if (this.postfix === '$') {\n // this.fillRectangle(this.params);\n // } else {\n // this.requestParameters(this.params);\n // //this.__(this.params);\n // }\n // break;\n\n // CSI Ps ; Pu ' z\n // CSI Pt; Pl; Pb; Pr$ z\n // case 'z':\n // if (this.postfix === '\\'') {\n // this.enableLocatorReporting(this.params);\n // } else if (this.postfix === '$') {\n // this.eraseRectangle(this.params);\n // }\n // break;\n\n // CSI Pm ' {\n // CSI Pt; Pl; Pb; Pr$ {\n // case '{':\n // if (this.postfix === '\\'') {\n // this.setLocatorEvents(this.params);\n // } else if (this.postfix === '$') {\n // this.selectiveEraseRectangle(this.params);\n // }\n // break;\n\n // CSI Ps ' |\n // case '|':\n // if (this.postfix === '\\'') {\n // this.requestLocatorPosition(this.params);\n // }\n // break;\n\n // CSI P m SP }\n // Insert P s Column(s) (default = 1) (DECIC), VT420 and up.\n // case '}':\n // if (this.postfix === ' ') {\n // this.insertColumns(this.params);\n // }\n // break;\n\n // CSI P m SP ~\n // Delete P s Column(s) (default = 1) (DECDC), VT420 and up\n // case '~':\n // if (this.postfix === ' ') {\n // this.deleteColumns(this.params);\n // }\n // break;\n\n default:\n this.error('Unknown CSI code: %s.', ch);\n break;\n }\n\n this.prefix = '';\n this.postfix = '';\n break;\n\n case dcs:\n if (ch === '\\x1b' || ch === '\\x07') {\n if (ch === '\\x1b') i++;\n\n switch (this.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n var pt = this.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this.scrollTop + 1)\n + ';'\n + (this.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this.send('\\x1bP' + +valid + '$r' + pt + '\\x1b\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n var pt = this.currentParam\n , valid = false;\n\n this.send('\\x1bP' + +valid + '+r' + pt + '\\x1b\\\\');\n break;\n\n default:\n this.error('Unknown DCS prefix: %s.', this.prefix);\n break;\n }\n\n this.currentParam = 0;\n this.prefix = '';\n this.state = normal;\n } else if (!this.currentParam) {\n if (!this.prefix && ch !== '$' && ch !== '+') {\n this.currentParam = ch;\n } else if (this.prefix.length === 2) {\n this.currentParam = ch;\n } else {\n this.prefix += ch;\n }\n } else {\n this.currentParam += ch;\n }\n break;\n\n case ignore:\n // For PM and APC.\n if (ch === '\\x1b' || ch === '\\x07') {\n if (ch === '\\x1b') i++;\n this.state = normal;\n }\n break;\n }\n }\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = '\\x08'; // ^H\n break;\n }\n result.key = '\\x7f'; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = '\\x1b[Z';\n break;\n }\n result.key = '\\t';\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = '\\r';\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = '\\x1b';\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n if (result.key == '\\x1b[1;3D') {\n result.key = '\\x1b[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = '\\x1bOD';\n } else {\n result.key = '\\x1b[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n if (result.key == '\\x1b[1;3C') {\n result.key = '\\x1b[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = '\\x1bOC';\n } else {\n result.key = '\\x1b[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == '\\x1b[1;3A') {\n result.key = '\\x1b[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = '\\x1bOA';\n } else {\n result.key = '\\x1b[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == '\\x1b[1;3B') {\n result.key = '\\x1b[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = '\\x1bOB';\n } else {\n result.key = '\\x1b[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = '\\x1b[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = '\\x1b[3;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = '\\x1b[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = '\\x1bOH';\n else\n result.key = '\\x1b[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = '\\x1b[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = '\\x1bOF';\n else\n result.key = '\\x1b[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = '\\x1b[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = '\\x1b[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = '\\x1bOP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = '\\x1bOQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = '\\x1bOR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = '\\x1b[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = '\\x1bOS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = '\\x1b[15;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = '\\x1b[17;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = '\\x1b[18;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = '\\x1b[19;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = '\\x1b[20;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = '\\x1b[21;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = '\\x1b[23;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = '\\x1b[24;' + (modifiers + 1) + '~';\n } else {\n result.key = '\\x1b[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = '\\x1b' + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = '\\x1b`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = '\\x1b' + (ev.keyCode - 48);\n }\n }\n break;\n }\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines[i].length < x) {\n this.lines[i].push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines[i].length > x) {\n this.lines[i].pop();\n }\n }\n }\n this.setupStops(j);\n this.cols = x;\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += 8) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines[this.ybase + y]\n , ch = [this.eraseAttr(), ' ', 1]; // xterm\n\n\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines[this.ybase + y]\n , ch = [this.eraseAttr(), ' ', 1]; // xterm\n\n x++;\n while (x--) line[x] = ch;\n\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines = [this.lines[this.ybase + this.y]];\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line/\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n this.state = normal;\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n this.y--;\n if (this.y < this.scrollTop) {\n this.y++;\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.splice(this.y + this.ybase, 0, this.blankLine(true));\n j = this.rows - 1 - this.scrollBottom;\n this.lines.splice(this.rows - 1 + this.ybase - j + 1, 1);\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n }\n this.state = normal;\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n this.state = normal;\n};\n\n\n/**\n * CSI\n */\n\n/**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\nTerminal.prototype.cursorUp = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.y -= param;\n if (this.y < 0) this.y = 0;\n};\n\n\n/**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\nTerminal.prototype.cursorDown = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.y += param;\n if (this.y >= this.rows) {\n this.y = this.rows - 1;\n }\n};\n\n\n/**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\nTerminal.prototype.cursorForward = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.x += param;\n if (this.x >= this.cols) {\n this.x = this.cols - 1;\n }\n};\n\n\n/**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\nTerminal.prototype.cursorBackward = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.x -= param;\n if (this.x < 0) this.x = 0;\n};\n\n\n/**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\nTerminal.prototype.cursorPos = function(params) {\n var row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this.rows) {\n row = this.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this.cols) {\n col = this.cols - 1;\n }\n\n this.x = col;\n this.y = row;\n};\n\n\n/**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\nTerminal.prototype.eraseInDisplay = function(params) {\n var j;\n switch (params[0]) {\n case 0:\n this.eraseRight(this.x, this.y);\n j = this.y + 1;\n for (; j < this.rows; j++) {\n this.eraseLine(j);\n }\n break;\n case 1:\n this.eraseLeft(this.x, this.y);\n j = this.y;\n while (j--) {\n this.eraseLine(j);\n }\n break;\n case 2:\n j = this.rows;\n while (j--) this.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n};\n\n\n/**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\nTerminal.prototype.eraseInLine = function(params) {\n switch (params[0]) {\n case 0:\n this.eraseRight(this.x, this.y);\n break;\n case 1:\n this.eraseLeft(this.x, this.y);\n break;\n case 2:\n this.eraseLine(this.y);\n break;\n }\n};\n\n\n/**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\nTerminal.prototype.charAttributes = function(params) {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this.curAttr = this.defAttr;\n return;\n }\n\n var l = params.length\n , i = 0\n , flags = this.curAttr >> 18\n , fg = (this.curAttr >> 9) & 0x1ff\n , bg = this.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this.defAttr >> 18;\n fg = (this.defAttr >> 9) & 0x1ff;\n bg = this.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this.defAttr >> 9) & 0x1ff;\n bg = this.defAttr & 0x1ff;\n } else {\n this.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this.curAttr = (flags << 18) | (fg << 9) | bg;\n};\n\n\n/**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\nTerminal.prototype.deviceStatus = function(params) {\n if (!this.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this.send('\\x1b[0n');\n break;\n case 6:\n // cursor position\n this.send('\\x1b['\n + (this.y + 1)\n + ';'\n + (this.x + 1)\n + 'R');\n break;\n }\n } else if (this.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this.send('\\x1b[?'\n + (this.y + 1)\n + ';'\n + (this.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send('\\x1b[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send('\\x1b[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send('\\x1b[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send('\\x1b[?50n');\n break;\n }\n }\n};\n\n\n/**\n * Additions\n */\n\n/**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\nTerminal.prototype.insertChars = function(params) {\n var param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this.y + this.ybase;\n j = this.x;\n ch = [this.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this.cols) {\n this.lines[row].splice(j++, 0, ch);\n this.lines[row].pop();\n }\n};\n\n/**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\nTerminal.prototype.cursorNextLine = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.y += param;\n if (this.y >= this.rows) {\n this.y = this.rows - 1;\n }\n this.x = 0;\n};\n\n\n/**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\nTerminal.prototype.cursorPrecedingLine = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.y -= param;\n if (this.y < 0) this.y = 0;\n this.x = 0;\n};\n\n\n/**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\nTerminal.prototype.cursorCharAbsolute = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.x = param - 1;\n};\n\n\n/**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\nTerminal.prototype.insertLines = function(params) {\n var param, row, j;\n\n param = params[0];\n if (param < 1) param = 1;\n row = this.y + this.ybase;\n\n j = this.rows - 1 - this.scrollBottom;\n j = this.rows - 1 + this.ybase - j + 1;\n\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this.lines.splice(row, 0, this.blankLine(true));\n this.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.y);\n this.updateRange(this.scrollBottom);\n};\n\n\n/**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\nTerminal.prototype.deleteLines = function(params) {\n var param, row, j;\n\n param = params[0];\n if (param < 1) param = 1;\n row = this.y + this.ybase;\n\n j = this.rows - 1 - this.scrollBottom;\n j = this.rows - 1 + this.ybase - j;\n\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this.lines.splice(j + 1, 0, this.blankLine(true));\n this.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.y);\n this.updateRange(this.scrollBottom);\n};\n\n\n/**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\nTerminal.prototype.deleteChars = function(params) {\n var param, row, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this.y + this.ybase;\n ch = [this.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this.lines[row].splice(this.x, 1);\n this.lines[row].push(ch);\n }\n};\n\n/**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\nTerminal.prototype.eraseChars = function(params) {\n var param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this.y + this.ybase;\n j = this.x;\n ch = [this.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this.cols) {\n this.lines[row][j++] = ch;\n }\n};\n\n/**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\nTerminal.prototype.charPosAbsolute = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.x = param - 1;\n if (this.x >= this.cols) {\n this.x = this.cols - 1;\n }\n};\n\n\n/**\n * 141 61 a * HPR -\n * Horizontal Position Relative\n * reuse CSI Ps C ?\n */\nTerminal.prototype.HPositionRelative = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.x += param;\n if (this.x >= this.cols) {\n this.x = this.cols - 1;\n }\n};\n\n\n/**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\nTerminal.prototype.sendDeviceAttributes = function(params) {\n if (params[0] > 0) return;\n\n if (!this.prefix) {\n if (this.is('xterm')\n || this.is('rxvt-unicode')\n || this.is('screen')) {\n this.send('\\x1b[?1;2c');\n } else if (this.is('linux')) {\n this.send('\\x1b[?6c');\n }\n } else if (this.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this.is('xterm')) {\n this.send('\\x1b[>0;276;0c');\n } else if (this.is('rxvt-unicode')) {\n this.send('\\x1b[>85;95;0c');\n } else if (this.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this.send(params[0] + 'c');\n } else if (this.is('screen')) {\n this.send('\\x1b[>83;40003;0c');\n }\n }\n};\n\n\n/**\n * CSI Pm d\n * Line Position Absolute [row] (default = [1,column]) (VPA).\n */\nTerminal.prototype.linePosAbsolute = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.y = param - 1;\n if (this.y >= this.rows) {\n this.y = this.rows - 1;\n }\n};\n\n\n/**\n * 145 65 e * VPR - Vertical Position Relative\n * reuse CSI Ps B ?\n */\nTerminal.prototype.VPositionRelative = function(params) {\n var param = params[0];\n if (param < 1) param = 1;\n this.y += param;\n if (this.y >= this.rows) {\n this.y = this.rows - 1;\n }\n};\n\n\n/**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\nTerminal.prototype.HVPosition = function(params) {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this.y = params[0] - 1;\n if (this.y >= this.rows) {\n this.y = this.rows - 1;\n }\n\n this.x = params[1] - 1;\n if (this.x >= this.cols) {\n this.x = this.cols - 1;\n }\n};\n\n\n/**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\nTerminal.prototype.setMode = function(params) {\n if (typeof params === 'object') {\n var l = params.length\n , i = 0;\n\n for (; i < l; i++) {\n this.setMode(params[i]);\n }\n\n return;\n }\n\n if (!this.prefix) {\n switch (params) {\n case 4:\n this.insertMode = true;\n break;\n case 20:\n //this.convertEol = true;\n break;\n }\n } else if (this.prefix === '?') {\n switch (params) {\n case 1:\n this.applicationCursor = true;\n break;\n case 2:\n this.setgCharset(0, Terminal.charsets.US);\n this.setgCharset(1, Terminal.charsets.US);\n this.setgCharset(2, Terminal.charsets.US);\n this.setgCharset(3, Terminal.charsets.US);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this.savedCols = this.cols;\n this.resize(132, this.rows);\n break;\n case 6:\n this.originMode = true;\n break;\n case 7:\n this.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this.log('Serial port requested application keypad.');\n this.applicationKeypad = true;\n this.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this.x10Mouse = params === 9;\n this.vt200Mouse = params === 1000;\n this.normalMouse = params > 1000;\n this.mouseEvents = true;\n this.element.style.cursor = 'default';\n this.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\nTerminal.prototype.resetMode = function(params) {\n if (typeof params === 'object') {\n var l = params.length\n , i = 0;\n\n for (; i < l; i++) {\n this.resetMode(params[i]);\n }\n\n return;\n }\n\n if (!this.prefix) {\n switch (params) {\n case 4:\n this.insertMode = false;\n break;\n case 20:\n //this.convertEol = false;\n break;\n }\n } else if (this.prefix === '?') {\n switch (params) {\n case 1:\n this.applicationCursor = false;\n break;\n case 3:\n if (this.cols === 132 && this.savedCols) {\n this.resize(this.savedCols, this.rows);\n }\n delete this.savedCols;\n break;\n case 6:\n this.originMode = false;\n break;\n case 7:\n this.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this.log('Switching back to normal keypad.');\n this.applicationKeypad = false;\n this.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this.x10Mouse = false;\n this.vt200Mouse = false;\n this.normalMouse = false;\n this.mouseEvents = false;\n this.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this.normal) {\n this.lines = this.normal.lines;\n this.ybase = this.normal.ybase;\n this.ydisp = this.normal.ydisp;\n this.x = this.normal.x;\n this.y = this.normal.y;\n this.scrollTop = this.normal.scrollTop;\n this.scrollBottom = this.normal.scrollBottom;\n this.tabs = this.normal.tabs;\n this.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this.refresh(0, this.rows - 1);\n this.showCursor();\n }\n break;\n }\n }\n};\n\n\n/**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\nTerminal.prototype.setScrollRegion = function(params) {\n if (this.prefix) return;\n this.scrollTop = (params[0] || 1) - 1;\n this.scrollBottom = (params[1] || this.rows) - 1;\n this.x = 0;\n this.y = 0;\n};\n\n\n/**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\nTerminal.prototype.saveCursor = function(params) {\n this.savedX = this.x;\n this.savedY = this.y;\n};\n\n\n/**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\nTerminal.prototype.restoreCursor = function(params) {\n this.x = this.savedX || 0;\n this.y = this.savedY || 0;\n};\n\n\n/**\n * Lesser Used\n */\n\n/**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\nTerminal.prototype.cursorForwardTab = function(params) {\n var param = params[0] || 1;\n while (param--) {\n this.x = this.nextStop();\n }\n};\n\n\n/**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\nTerminal.prototype.scrollUp = function(params) {\n var param = params[0] || 1;\n while (param--) {\n this.lines.splice(this.ybase + this.scrollTop, 1);\n this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine());\n }\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n};\n\n\n/**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\nTerminal.prototype.scrollDown = function(params) {\n var param = params[0] || 1;\n while (param--) {\n this.lines.splice(this.ybase + this.scrollBottom, 1);\n this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine());\n }\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n};\n\n\n/**\n * CSI Ps ; Ps ; Ps ; Ps ; Ps T\n * Initiate highlight mouse tracking. Parameters are\n * [func;startx;starty;firstrow;lastrow]. See the section Mouse\n * Tracking.\n */\nTerminal.prototype.initMouseTracking = function(params) {\n // Relevant: DECSET 1001\n};\n\n\n/**\n * CSI > Ps; Ps T\n * Reset one or more features of the title modes to the default\n * value. Normally, \"reset\" disables the feature. It is possi-\n * ble to disable the ability to reset features by compiling a\n * different default for the title modes into xterm.\n * Ps = 0 -> Do not set window/icon labels using hexadecimal.\n * Ps = 1 -> Do not query window/icon labels using hexadeci-\n * mal.\n * Ps = 2 -> Do not set window/icon labels using UTF-8.\n * Ps = 3 -> Do not query window/icon labels using UTF-8.\n * (See discussion of \"Title Modes\").\n */\nTerminal.prototype.resetTitleModes = function(params) {\n ;\n};\n\n\n/**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\nTerminal.prototype.cursorBackwardTab = function(params) {\n var param = params[0] || 1;\n while (param--) {\n this.x = this.prevStop();\n }\n};\n\n\n/**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\nTerminal.prototype.repeatPrecedingCharacter = function(params) {\n var param = params[0] || 1\n , line = this.lines[this.ybase + this.y]\n , ch = line[this.x - 1] || [this.defAttr, ' ', 1];\n\n while (param--) line[this.x++] = ch;\n};\n\n\n/**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\nTerminal.prototype.tabClear = function(params) {\n var param = params[0];\n if (param <= 0) {\n delete this.tabs[this.x];\n } else if (param === 3) {\n this.tabs = {};\n }\n};\n\n\n/**\n * CSI Pm i Media Copy (MC).\n * Ps = 0 -> Print screen (default).\n * Ps = 4 -> Turn off printer controller mode.\n * Ps = 5 -> Turn on printer controller mode.\n * CSI ? Pm i\n * Media Copy (MC, DEC-specific).\n * Ps = 1 -> Print line containing cursor.\n * Ps = 4 -> Turn off autoprint mode.\n * Ps = 5 -> Turn on autoprint mode.\n * Ps = 1 0 -> Print composed display, ignores DECPEX.\n * Ps = 1 1 -> Print all pages.\n */\nTerminal.prototype.mediaCopy = function(params) {\n ;\n};\n\n\n/**\n * CSI > Ps; Ps m\n * Set or reset resource-values used by xterm to decide whether\n * to construct escape sequences holding information about the\n * modifiers pressed with a given key. The first parameter iden-\n * tifies the resource to set/reset. The second parameter is the\n * value to assign to the resource. If the second parameter is\n * omitted, the resource is reset to its initial value.\n * Ps = 1 -> modifyCursorKeys.\n * Ps = 2 -> modifyFunctionKeys.\n * Ps = 4 -> modifyOtherKeys.\n * If no parameters are given, all resources are reset to their\n * initial values.\n */\nTerminal.prototype.setResources = function(params) {\n ;\n};\n\n\n/**\n * CSI > Ps n\n * Disable modifiers which may be enabled via the CSI > Ps; Ps m\n * sequence. This corresponds to a resource value of \"-1\", which\n * cannot be set with the other sequence. The parameter identi-\n * fies the resource to be disabled:\n * Ps = 1 -> modifyCursorKeys.\n * Ps = 2 -> modifyFunctionKeys.\n * Ps = 4 -> modifyOtherKeys.\n * If the parameter is omitted, modifyFunctionKeys is disabled.\n * When modifyFunctionKeys is disabled, xterm uses the modifier\n * keys to make an extended sequence of functions rather than\n * adding a parameter to each function key to denote the modi-\n * fiers.\n */\nTerminal.prototype.disableModifiers = function(params) {\n ;\n};\n\n\n/**\n * CSI > Ps p\n * Set resource value pointerMode. This is used by xterm to\n * decide whether to hide the pointer cursor as the user types.\n * Valid values for the parameter:\n * Ps = 0 -> never hide the pointer.\n * Ps = 1 -> hide if the mouse tracking mode is not enabled.\n * Ps = 2 -> always hide the pointer. If no parameter is\n * given, xterm uses the default, which is 1 .\n */\nTerminal.prototype.setPointerMode = function(params) {\n ;\n};\n\n\n/**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\nTerminal.prototype.softReset = function(params) {\n this.cursorHidden = false;\n this.insertMode = false;\n this.originMode = false;\n this.wraparoundMode = false; // autowrap\n this.applicationKeypad = false; // ?\n this.viewport.syncScrollArea();\n this.applicationCursor = false;\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.curAttr = this.defAttr;\n this.x = this.y = 0; // ?\n this.charset = null;\n this.glevel = 0; // ??\n this.charsets = [null]; // ??\n};\n\n\n/**\n * CSI Ps$ p\n * Request ANSI mode (DECRQM). For VT300 and up, reply is\n * CSI Ps; Pm$ y\n * where Ps is the mode number as in RM, and Pm is the mode\n * value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n */\nTerminal.prototype.requestAnsiMode = function(params) {\n ;\n};\n\n\n/**\n * CSI ? Ps$ p\n * Request DEC private mode (DECRQM). For VT300 and up, reply is\n * CSI ? Ps; Pm$ p\n * where Ps is the mode number as in DECSET, Pm is the mode value\n * as in the ANSI DECRQM.\n */\nTerminal.prototype.requestPrivateMode = function(params) {\n ;\n};\n\n\n/**\n * CSI Ps ; Ps \" p\n * Set conformance level (DECSCL). Valid values for the first\n * parameter:\n * Ps = 6 1 -> VT100.\n * Ps = 6 2 -> VT200.\n * Ps = 6 3 -> VT300.\n * Valid values for the second parameter:\n * Ps = 0 -> 8-bit controls.\n * Ps = 1 -> 7-bit controls (always set for VT100).\n * Ps = 2 -> 8-bit controls.\n */\nTerminal.prototype.setConformanceLevel = function(params) {\n ;\n};\n\n\n/**\n * CSI Ps q Load LEDs (DECLL).\n * Ps = 0 -> Clear all LEDS (default).\n * Ps = 1 -> Light Num Lock.\n * Ps = 2 -> Light Caps Lock.\n * Ps = 3 -> Light Scroll Lock.\n * Ps = 2 1 -> Extinguish Num Lock.\n * Ps = 2 2 -> Extinguish Caps Lock.\n * Ps = 2 3 -> Extinguish Scroll Lock.\n */\nTerminal.prototype.loadLEDs = function(params) {\n ;\n};\n\n\n/**\n * CSI Ps SP q\n * Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n */\nTerminal.prototype.setCursorStyle = function(params) {\n ;\n};\n\n\n/**\n * CSI Ps \" q\n * Select character protection attribute (DECSCA). Valid values\n * for the parameter:\n * Ps = 0 -> DECSED and DECSEL can erase (default).\n * Ps = 1 -> DECSED and DECSEL cannot erase.\n * Ps = 2 -> DECSED and DECSEL can erase.\n */\nTerminal.prototype.setCharProtectionAttr = function(params) {\n ;\n};\n\n\n/**\n * CSI ? Pm r\n * Restore DEC Private Mode Values. The value of Ps previously\n * saved is restored. Ps values are the same as for DECSET.\n */\nTerminal.prototype.restorePrivateValues = function(params) {\n ;\n};\n\n\n/**\n * CSI Pt; Pl; Pb; Pr; Ps$ r\n * Change Attributes in Rectangular Area (DECCARA), VT400 and up.\n * Pt; Pl; Pb; Pr denotes the rectangle.\n * Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7.\n * NOTE: xterm doesn't enable this code by default.\n */\nTerminal.prototype.setAttrInRectangle = function(params) {\n var t = params[0]\n , l = params[1]\n , b = params[2]\n , r = params[3]\n , attr = params[4];\n\n var line\n , i;\n\n for (; t < b + 1; t++) {\n line = this.lines[this.ybase + t];\n for (i = l; i < r; i++) {\n line[i] = [attr, line[i][1]];\n }\n }\n\n // this.maxRange();\n this.updateRange(params[0]);\n this.updateRange(params[2]);\n};\n\n\n/**\n * CSI Pc; Pt; Pl; Pb; Pr$ x\n * Fill Rectangular Area (DECFRA), VT420 and up.\n * Pc is the character to use.\n * Pt; Pl; Pb; Pr denotes the rectangle.\n * NOTE: xterm doesn't enable this code by default.\n */\nTerminal.prototype.fillRectangle = function(params) {\n var ch = params[0]\n , t = params[1]\n , l = params[2]\n , b = params[3]\n , r = params[4];\n\n var line\n , i;\n\n for (; t < b + 1; t++) {\n line = this.lines[this.ybase + t];\n for (i = l; i < r; i++) {\n line[i] = [line[i][0], String.fromCharCode(ch)];\n }\n }\n\n // this.maxRange();\n this.updateRange(params[1]);\n this.updateRange(params[3]);\n};\n\n\n/**\n * CSI Ps ; Pu ' z\n * Enable Locator Reporting (DECELR).\n * Valid values for the first parameter:\n * Ps = 0 -> Locator disabled (default).\n * Ps = 1 -> Locator enabled.\n * Ps = 2 -> Locator enabled for one report, then disabled.\n * The second parameter specifies the coordinate unit for locator\n * reports.\n * Valid values for the second parameter:\n * Pu = 0 <- or omitted -> default to character cells.\n * Pu = 1 <- device physical pixels.\n * Pu = 2 <- character cells.\n */\nTerminal.prototype.enableLocatorReporting = function(params) {\n var val = params[0] > 0;\n //this.mouseEvents = val;\n //this.decLocator = val;\n};\n\n\n/**\n * CSI Pt; Pl; Pb; Pr$ z\n * Erase Rectangular Area (DECERA), VT400 and up.\n * Pt; Pl; Pb; Pr denotes the rectangle.\n * NOTE: xterm doesn't enable this code by default.\n */\nTerminal.prototype.eraseRectangle = function(params) {\n var t = params[0]\n , l = params[1]\n , b = params[2]\n , r = params[3];\n\n var line\n , i\n , ch;\n\n ch = [this.eraseAttr(), ' ', 1]; // xterm?\n\n for (; t < b + 1; t++) {\n line = this.lines[this.ybase + t];\n for (i = l; i < r; i++) {\n line[i] = ch;\n }\n }\n\n // this.maxRange();\n this.updateRange(params[0]);\n this.updateRange(params[2]);\n};\n\n\n/**\n * CSI P m SP }\n * Insert P s Column(s) (default = 1) (DECIC), VT420 and up.\n * NOTE: xterm doesn't enable this code by default.\n */\nTerminal.prototype.insertColumns = function() {\n var param = params[0]\n , l = this.ybase + this.rows\n , ch = [this.eraseAttr(), ' ', 1] // xterm?\n , i;\n\n while (param--) {\n for (i = this.ybase; i < l; i++) {\n this.lines[i].splice(this.x + 1, 0, ch);\n this.lines[i].pop();\n }\n }\n\n this.maxRange();\n};\n\n\n/**\n * CSI P m SP ~\n * Delete P s Column(s) (default = 1) (DECDC), VT420 and up\n * NOTE: xterm doesn't enable this code by default.\n */\nTerminal.prototype.deleteColumns = function() {\n var param = params[0]\n , l = this.ybase + this.rows\n , ch = [this.eraseAttr(), ' ', 1] // xterm?\n , i;\n\n while (param--) {\n for (i = this.ybase; i < l; i++) {\n this.lines[i].splice(this.x, 1);\n this.lines[i].push(ch);\n }\n }\n\n this.maxRange();\n};\n\n/**\n * Character Sets\n */\n\nTerminal.charsets = {};\n\n// DEC Special Character and Line Drawing Set.\n// http://vt100.net/docs/vt102-ug/table5-13.html\n// A lot of curses apps use this if they see TERM=xterm.\n// testing: echo -e '\\e(0a\\e(B'\n// The xterm output sometimes seems to conflict with the\n// reference above. xterm seems in line with the reference\n// when running vttest however.\n// The table below now uses xterm's output from vttest.\nTerminal.charsets.SCLD = { // (0\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\nTerminal.charsets.UK = null; // (A\nTerminal.charsets.US = null; // (B (USASCII)\nTerminal.charsets.Dutch = null; // (4\nTerminal.charsets.Finnish = null; // (C or (5\nTerminal.charsets.French = null; // (R\nTerminal.charsets.FrenchCanadian = null; // (Q\nTerminal.charsets.German = null; // (K\nTerminal.charsets.Italian = null; // (Y\nTerminal.charsets.NorwegianDanish = null; // (E or (6\nTerminal.charsets.Spanish = null; // (Z\nTerminal.charsets.Swedish = null; // (H or (7\nTerminal.charsets.Swiss = null; // (=\nTerminal.charsets.ISOLatin = null; // /A\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction isBoldBroken(document) {\n var body = document.getElementsByTagName('body')[0];\n var el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n var w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n var w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\nvar wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n var COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n var min = 0;\n var max = COMBINING.length - 1;\n var mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n return 1 +\n (\n ucs >= 0x1100 &&\n (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs == 0x2329 ||\n ucs == 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)\n )\n );\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport let contains = function(arr, el) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic.js';\n\nlet isNode = (typeof navigator == 'undefined') ? true : false;\nlet userAgent = (isNode) ? 'node' : navigator.userAgent;\nlet platform = (isNode) ? 'node' : navigator.platform;\n\nexport let isFirefox = !!~userAgent.indexOf('Firefox');\nexport let isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport let isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport let isIpad = platform === 'iPad';\nexport let isIphone = platform === 'iPhone';\nexport let isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasureElement: HTMLElement\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n this.syncScrollArea();\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(charSize?: ClientRect): void {\n var size = charSize || this.charMeasureElement.getBoundingClientRect();\n if (size.height > 0) {\n var rowHeightChanged = size.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = size.height;\n this.viewportElement.style.lineHeight = size.height + 'px';\n this.terminal.rowContainer.style.lineHeight = size.height + 'px';\n }\n var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = size.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n var size = this.charMeasureElement.getBoundingClientRect();\n if (size.height !== this.currentRowHeight) {\n this.refresh(size);\n }\n }\n\n // Sync scrollTop\n var scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n var diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n var multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nfunction EventEmitter() {\n this._events = this._events || {};\n}\n\nEventEmitter.prototype.addListener = function(type, listener) {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.removeListener = function(type, listener) {\n if (!this._events[type]) return;\n\n var obj = this._events[type]\n , i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n};\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n if (this._events[type]) delete this._events[type];\n};\n\nEventEmitter.prototype.once = function(type, listener) {\n var self = this;\n function on() {\n var args = Array.prototype.slice.call(arguments);\n this.removeListener(type, on);\n return listener.apply(this, args);\n }\n on.listener = listener;\n return this.on(type, on);\n};\n\nEventEmitter.prototype.emit = function(type) {\n if (!this._events[type]) return;\n\n var args = Array.prototype.slice.call(arguments, 1)\n , obj = this._events[type]\n , l = obj.length\n , i = 0;\n\n for (; i < l; i++) {\n obj[i].apply(this, args);\n }\n};\n\nEventEmitter.prototype.listeners = function(type) {\n return this._events[type] = this._events[type] || [];\n};\n\nexport { EventEmitter };\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n var self = this;\n setTimeout(function() {\n self.compositionPosition.end = self.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n var currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n }\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n var self = this;\n this.isSendingComposition = true;\n setTimeout(function () {\n // Ensure that the input has not already been sent\n if (self.isSendingComposition) {\n self.isSendingComposition = false;\n var input;\n if (self.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = self.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = self.textarea.value.substring(currentCompositionPosition.start);\n }\n self.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n var oldValue = this.textarea.value;\n var self = this;\n setTimeout(function() {\n // Ignore if a composition has started since the timeout\n if (!self.isComposing) {\n var newValue = self.textarea.value;\n var diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n self.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n var cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n var xtermRows = this.terminal.element.querySelector('.xterm-rows');\n var cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n var compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(this.updateCompositionElements.bind(this, true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (Number.isNaN(x) || Number.isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(parentElement: HTMLElement) {\n super();\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n this.syncScrollArea();\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = false; // autowrap\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"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C,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC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"} \ No newline at end of file diff --git a/package.json b/package.json index 8e81c204..2eaaf2ab 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "2.2.3", + "version": "2.3.0", "ignore": [ "demo", "test", From c3256556aaaf0e7f4f26441a4e9f8dabdb4fa1b7 Mon Sep 17 00:00:00 2001 From: Vincent Woo Date: Wed, 8 Feb 2017 15:33:20 -0800 Subject: [PATCH 104/211] Fix missing Number.isNaN in IE See https://github.com/sourcelair/xterm.js/pull/525#issuecomment-278497452 --- src/xterm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index b2740683..314a76d0 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1715,7 +1715,7 @@ Terminal.prototype.error = function() { * @param {number} y The number of rows to resize to. */ Terminal.prototype.resize = function(x, y) { - if (Number.isNaN(x) || Number.isNaN(y)) { + if (isNaN(x) || isNaN(y)) { return; } From 639a2fd50915b97a0e98d5158f9f7d5953205aa0 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 8 Feb 2017 23:51:47 +0000 Subject: [PATCH 105/211] Bump version to 2.3.1 Signed-off-by: Paris Kasidiaris --- bower.json | 2 +- dist/xterm.js | 2 +- dist/xterm.js.map | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index a7b2929a..95b72e97 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "xterm.js", - "version": "2.3.0", + "version": "2.3.1", "ignore": ["demo", "test", ".gitignore"], "main": [ "dist/xterm.js", diff --git a/dist/xterm.js b/dist/xterm.js index 23a014cf..93766079 100644 --- a/dist/xterm.js +++ b/dist/xterm.js @@ -3525,7 +3525,7 @@ Terminal.prototype.error = function () { this.context.console.error.apply(this.context.console, args); }; Terminal.prototype.resize = function (x, y) { - if (Number.isNaN(x) || Number.isNaN(y)) { + if (isNaN(x) || isNaN(y)) { return; } var line, el, i, j, ch, addToY; diff --git a/dist/xterm.js.map b/dist/xterm.js.map index 5fe7bf06..0c06e145 100644 --- a/dist/xterm.js.map +++ b/dist/xterm.js.map @@ -1 +1 @@ -{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (Number.isNaN(x) || Number.isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(parentElement: HTMLElement) {\n super();\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n this.syncScrollArea();\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = false; // autowrap\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"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C,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1D,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1D,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1D,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1D,CAAC,OAAO,EAAE,OAAO,CAAC;KACnB,CAAC;IAEF,kBAAkB,GAAG;QACnB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/B,IAAI,GAAG,CAAC;QACR,EAAE,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,CAAC,KAAK,CAAC;QACf,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;YAClB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAClC,EAAE,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,IAAI;gBACF,MAAM,CAAC,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IACD,iBAAiB,GAAG;QAElB,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAClB,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAEtB,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChB,MAAM,CAAC,CAAC,CAAC;QAEX,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,CAAC,CAAC;QACX,CAAC;QACD,MAAM,CAAC,CAAC,CAAC;IACX,CAAC;IACD,gBAAgB,GAAG;QACjB,MAAM,CAAC,CACL,GAAG,IAAI,MAAM,IAAI,CACf,GAAG,IAAI,MAAM;YACb,GAAG,KAAK,MAAM;YACd,GAAG,KAAK,MAAM;YACd,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,KAAK,MAAM,CAAC;YAClD,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;YAChC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;YAChC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;YAChC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;YAChC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;YAChC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;YAChC,CAAC,GAAG,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,CAAC;YAClC,CAAC,GAAG,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,CAAC,OAAO,CAAC;AACjB,CAAC,CAAC,CAAC,EAAC,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAC,CAAC,CAAC;;;;ADriDzB,IAAA,iBAAA,GAAA,OAAA,CAAA,mBAAA,CAAA,CAAuC;AAEvC,IAAA,UAAA,GAAA,OAAA,CAAA,YAAA,CAAA,CAAuD;AAEvD,IAAM,kBAAkB,GAAsE,EAAE,CAAC;AACjG,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAlD,CAAkD,OAAO,CAAC,IAAI,EAAE,CAAhE,CAAkD,CAAc,CAAC;AACjE,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAjD,CAAiD,OAAO,CAAC,QAAQ,EAAE,CAAnE,CAAiD,CAAkB,CAAC;AACpE,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,iBAA/C,CAAA,EAAiD,CAAC,EAAE,CAAC,CAAC;AACtD,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,iBAA/C,CAAA,EAAiD,CAAC,EAAE,CAAC,CAAC;AACtD,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAjD,CAAiD,OAAO,CAAC,cAAc,EAAE,CAAzE,CAAiD,CAAwB,CAAC;AAC1E,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAjD,CAAiD,OAAO,CAAC,SAAS,EAAE,CAApE,CAAiD,CAAmB,CAAC;AACrE,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAjD,CAAiD,OAAO,CAAC,GAAG,EAAE,CAA9D,CAAiD,CAAa,CAAC;AAC/D,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAjD,CAAiD,OAAO,CAAC,QAAQ,EAAE,CAAnE,CAAiD,CAAkB,CAAC;AACpE,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAjD,CAAiD,OAAO,CAAC,OAAO,EAAE,CAAlE,CAAiD,CAAiB,CAAC;AACnE,kBAAkB,CAAC,iBAAnB,CAAA,EAAqB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,OAAO,IAAK,MAAlD,CAAkD,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAtF,CAAkD,CAAoC,CAAC;AAGvF,IAAM,mBAAmB,GAA6D,EAAE,CAAC;AACzF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC;IACrB,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC;IAC1B,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;AACzC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC;IACrB,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC;IAC1B,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC;IACrB,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC;IAC1B,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,KAAK,EAAE,CAAC;AACnB,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IACf,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAE1C,QAAQ,CAAC,YAAY,EAAE,CAAC;IACxB,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AACF,mBAAmB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,EAAE,QAAQ;IAG1C,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,CAAC,EAAE,UAA1B,CAAA,eAAyC,CAAC,CAAC;IACzC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,YAAY,EAAE,CAAC;AACxB,CAAC,CAAC;AACF,mBAAmB,CAAC,iBAApB,CAAA,EAAsB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAA1C,CAA0C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAA7E,CAA0C,CAAmC,CAAC;AAE9E,IAAM,oBAAoB,GAA8C,EAAE,CAAC;AAC3E,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAA7D,CAAwC,CAAqB,CAAC;AAC9D,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAA7D,CAAwC,CAAqB,CAAC;AAC9D,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAA7D,CAAwC,CAAqB,CAAC;AAC9D,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAA/E,CAAwC,CAAuC,CAAC;AAChF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAnF,CAAwC,CAA2C,CAAC;AACpF,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAA9D,CAAwC,CAAsB,CAAC;AAC/D,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAA9D,CAAwC,CAAsB,CAAC;AAC/D,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAA9D,CAAwC,CAAsB,CAAC;AAC/D,oBAAoB,CAAC,IAAI,CAAC,GAAG,UAAC,MAAM,IAAK,MAAzC,CAAyC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAhE,CAAyC,CAAuB,CAAC;AACjE,oBAAoB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAAxC,CAAwC,MAAM,CAAC,aAAa,EAAE,CAA9D,CAAwC,CAAsB,CAAC;AAC/D,oBAAoB,CAAC,iBAArB,CAAA,EAAuB,CAAC,GAAG,CAAC,GAAG,UAAC,MAAM,IAAK,MAA3C,CAA2C,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAA9E,CAA2C,CAAmC,CAAC;AAE/E,IAAM,eAAe,GAAyH,EAAE,CAAC;AACjJ,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAA/E,CAAoD,CAA2B,CAAC;AAChF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA5E,CAAoD,CAAwB,CAAC;AAC7E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAA9E,CAAoD,CAA0B,CAAC;AAC/E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAjF,CAAoD,CAA6B,CAAC;AAClF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAlF,CAAoD,CAA8B,CAAC;AACnF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAlF,CAAoD,CAA8B,CAAC;AACnF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAvF,CAAoD,CAAmC,CAAC;AACxF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAtF,CAAoD,CAAkC,CAAC;AACvF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAlF,CAAoD,CAA8B,CAAC;AACnF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAApF,CAAoD,CAAgC,CAAC;AACrF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAlF,CAAoD,CAA8B,CAAC;AACnF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAA/E,CAAoD,CAA2B,CAAC;AAChF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAA/E,CAAoD,CAA2B,CAAC;AAChF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAA/E,CAAoD,CAA2B,CAAC;AAChF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAA/E,CAAoD,CAA2B,CAAC;AAChF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA5E,CAAoD,CAAwB,CAAC;AAC7E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM;IAC7C,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACjC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC,CAAC;AACF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAA9E,CAAoD,CAA0B,CAAC;AAC/E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAArF,CAAoD,CAAiC,CAAC;AACtF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAnF,CAAoD,CAA+B,CAAC;AACpF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAArF,CAAoD,CAAiC,CAAC;AACtF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAA5F,CAAoD,CAAwC,CAAC;AAC7F,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAxF,CAAoD,CAAoC,CAAC;AACzF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAnF,CAAoD,CAA+B,CAAC;AACpF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAArF,CAAoD,CAAiC,CAAC;AACtF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAA9E,CAAoD,CAA0B,CAAC;AAC/E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA5E,CAAoD,CAAwB,CAAC;AAC7E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAA3E,CAAoD,CAAuB,CAAC;AAC5E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAA7E,CAAoD,CAAyB,CAAC;AAC9E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAlF,CAAoD,CAA8B,CAAC;AACnF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAK,MAApD,CAAoD,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAhF,CAAoD,CAA4B,CAAC;AACjF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM;IAC7C,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACf,KAAK,GAAG;YAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAAC,KAAK,CAAC;IAC7C,CAAC;AACH,CAAC,CAAC;AACF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IACtD,EAAE,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC;QACpB,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AACF,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,IAAK,MAA5C,CAA4C,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAA3E,CAA4C,CAA+B,CAAC;AAC5E,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,IAAK,MAA5C,CAA4C,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAtE,CAA4C,CAA0B,CAAC;AACvE,eAAe,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,IAAK,MAA5C,CAA4C,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAzE,CAA4C,CAA6B,CAAC;AAC1E,eAAe,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,CAAC,GAAG,UAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAK,MAAxE,CAAwE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAA3G,CAAwE,CAAmC,CAAC;AAE5G,IAAK,WASJ,CATD;AAAA,CAAA,UAAK,WAAW;IACd,WAAF,CAAA,WAAA,CAAA,QAAA,CAAA,GAAA,CAAA,CAAA,GAAA,QAAY,CAAA;IACV,WAAF,CAAA,WAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAa,CAAA;IACX,WAAF,CAAA,WAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,GAAA,WAAe,CAAA;IACb,WAAF,CAAA,WAAA,CAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA,KAAS,CAAA;IACP,WAAF,CAAA,WAAA,CAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA,KAAS,CAAA;IACP,WAAF,CAAA,WAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAa,CAAA;IACX,WAAF,CAAA,WAAA,CAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA,KAAS,CAAA;IACP,WAAF,CAAA,WAAA,CAAA,QAAA,CAAA,GAAA,CAAA,CAAA,GAAA,QAAY,CAAA;AACZ,CAAC,CAAD,CATK,WAAW,IAShB,CATK,WAAW,GAShB,EAAA,CAAA,CAAA,CAAC;AAOD,IAAA,MAAA,GAAA,CAAA;IAKE,gBACU,aAA4B,EAC5B,SAAc;QADd,IAAZ,CAAA,aAAyB,GAAb,aAAa,CAAe;QAC5B,IAAZ,CAAA,SAAqB,GAAT,SAAS,CAAK;QAEtB,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IACnC,CAAC;IAOM,MAAT,CAAA,SAAA,CAAA,KAAc,GAAZ,UAAa,IAAY;QACvB,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC;QAE1C,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAEnB,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;YAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC;YAC5C,IAAI,CAAC,SAAS,CAAC,cAAc,GAAG,EAAE,CAAC;QACrC,CAAC;QAED,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAC5C,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAI1B,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC;gBAGrC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;gBAC1C,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAEf,IAAI,CAAC,SAAS,CAAC,cAAc,GAAG,EAAE,CAAC;oBACnC,QAAQ,CAAC;gBACX,CAAC;gBACD,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC;gBAC5D,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YACxC,CAAC;YAED,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC;gBACnC,QAAQ,CAAC;YAEX,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpB,KAAK,WAAW,CAAC,MAAM;oBACrB,EAAE,CAAC,CAAC,EAAE,IAAI,kBAAkB,CAAC,CAAC,CAAC;wBAC7B,kBAAkB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;oBACnD,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;oBACvC,CAAC;oBACD,KAAK,CAAC;gBACR,KAAK,WAAW,CAAC,OAAO;oBACtB,EAAE,CAAC,CAAC,EAAE,IAAI,mBAAmB,CAAC,CAAC,CAAC;wBAC9B,mBAAmB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;wBAE9C,KAAK,CAAC;oBACR,CAAC;oBACD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAGX,KAAK,GAAG,CAAC;wBACT,KAAK,GAAG,CAAC;wBACT,KAAK,GAAG,CAAC;wBACT,KAAK,GAAG,CAAC;wBACT,KAAK,GAAG,CAAC;wBACT,KAAK,GAAG;4BACN,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gCACX,KAAK,GAAG;oCACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;oCAC5B,KAAK,CAAC;gCACR,KAAK,GAAG;oCACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;oCAC5B,KAAK,CAAC;gCACR,KAAK,GAAG;oCACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;oCAC5B,KAAK,CAAC;gCACR,KAAK,GAAG;oCACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;oCAC5B,KAAK,CAAC;gCACR,KAAK,GAAG;oCACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;oCAC5B,KAAK,CAAC;gCACR,KAAK,GAAG;oCACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;oCAC5B,KAAK,CAAC;4BACV,CAAC;4BACD,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;4BAClC,KAAK,CAAC;wBAKR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;4BAC5B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;4BAClC,IAAI,CAAC,SAAS,EAAE,CAAC;4BACjB,KAAK,CAAC;wBAKR,KAAK,GAAG;4BACN,KAAK,CAAC;wBAIR,KAAK,GAAG;4BACN,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;4BAC5B,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;4BAC5B,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;4BAC5B,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;4BAC5B,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;4BAC5B,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;4BAChC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;4BACnC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,IAAI,CAAC,SAAS,EAAE,CAAC;4BACjB,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;4BACxB,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;4BAChE,IAAI,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC;4BACxC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;4BACzC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,KAAK,CAAC;wBAGR,KAAK,GAAG;4BACN,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;4BACvD,IAAI,CAAC,SAAS,CAAC,iBAAiB,GAAG,KAAK,CAAC;4BACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;4BACzC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,KAAK,CAAC;wBAER;4BACE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;4BACjC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;4BACrD,KAAK,CAAC;oBACV,CAAC;oBACD,KAAK,CAAC;gBAER,KAAK,WAAW,CAAC,OAAO;oBACtB,EAAE,CAAC,CAAC,EAAE,IAAI,UAApB,CAAA,QAA4B,CAAC,CAAC,CAAC;wBACnB,EAAE,GAAG,UAAjB,CAAA,QAAyB,CAAC,EAAE,CAAC,CAAC;wBAClB,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;4BACf,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,CAAC;oBACH,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,EAAE,GAAG,UAAjB,CAAA,eAAgC,CAAC;oBACvB,CAAC;oBACD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBACxD,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;oBAC/B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACjC,KAAK,CAAC;gBAER,KAAK,WAAW,CAAC,GAAG;oBAIlB,EAAE,CAAC,CAAC,EAAE,KAAK,iBAArB,CAAA,EAAuB,CAAC,GAAG,IAAI,EAAE,KAAK,iBAAtC,CAAA,EAAwC,CAAC,GAAG,CAAC,CAAC,CAAC;wBACnC,EAAE,CAAC,CAAC,EAAE,KAAK,iBAAvB,CAAA,EAAyB,CAAC,GAAG,CAAC;4BAAC,IAAI,CAAC,SAAS,EAAE,CAAC;wBAEpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;wBAExD,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;4BACjC,KAAK,CAAC,CAAC;4BACP,KAAK,CAAC,CAAC;4BACP,KAAK,CAAC;gCACJ,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oCAC7B,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oCAChD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gCACnD,CAAC;gCACD,KAAK,CAAC;4BACR,KAAK,CAAC;gCAEJ,KAAK,CAAC;4BACR,KAAK,CAAC,CAAC;4BACP,KAAK,CAAC;gCAEJ,KAAK,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE,CAAC;4BACR,KAAK,EAAE;gCAEL,KAAK,CAAC;4BACR,KAAK,EAAE;gCAEL,KAAK,CAAC;4BACR,KAAK,EAAE;gCAEL,KAAK,CAAC;4BACR,KAAK,EAAE;gCAEL,KAAK,CAAC;4BACR,KAAK,EAAE;gCAEL,KAAK,CAAC;4BACR,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG,CAAC;4BACT,KAAK,GAAG;gCAEN,KAAK,CAAC;wBACV,CAAC;wBAED,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC;wBAC3B,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC;wBAChC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACnC,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;4BAClC,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;gCAC3B,IAAI,CAAC,SAAS,CAAC,YAAY;oCACzB,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;4BAC7D,CAAC;4BAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gCACtB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gCACxD,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,EAAE,CAAC;4BACnC,CAAC;wBACH,CAAC;wBAAC,IAAI,CAAC,CAAC;4BACN,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,EAAE,CAAC;wBACpC,CAAC;oBACH,CAAC;oBACD,KAAK,CAAC;gBAER,KAAK,WAAW,CAAC,SAAS;oBACxB,EAAE,CAAC,CAAC,EAAE,IAAI,oBAAoB,CAAC,CAAC,CAAC;wBAC/B,oBAAoB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;wBAC/B,KAAK,CAAC;oBACR,CAAC;oBACD,IAAI,CAAC,aAAa,EAAE,CAAC;oBAErB,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC;gBAEhC,KAAK,WAAW,CAAC,GAAG;oBAClB,EAAE,CAAC,CAAC,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;wBAC1B,eAAe,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;oBACtH,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;oBACpD,CAAC;oBAED,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACjC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC;oBAC3B,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,EAAE,CAAC;oBAC5B,KAAK,CAAC;gBAER,KAAK,WAAW,CAAC,GAAG;oBAClB,EAAE,CAAC,CAAC,EAAE,KAAK,iBAArB,CAAA,EAAuB,CAAC,GAAG,IAAI,EAAE,KAAK,iBAAtC,CAAA,EAAwC,CAAC,GAAG,CAAC,CAAC,CAAC;wBACnC,EAAE,CAAC,CAAC,EAAE,KAAK,iBAAvB,CAAA,EAAyB,CAAC,GAAG,CAAC;4BAAC,IAAI,CAAC,SAAS,EAAE,CAAC;wBAEpC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;4BAE9B,KAAK,EAAE;gCACL,KAAK,CAAC;4BAIR,KAAK,IAAI;gCACP,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAClC,KAAK,GAAG,KAAK,CAAC;gCAEhB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oCAEX,KAAK,IAAI;wCACP,EAAE,GAAG,KAAK,CAAC;wCACX,KAAK,CAAC;oCAGR,KAAK,IAAI;wCACP,EAAE,GAAG,MAAM,CAAC;wCACZ,KAAK,CAAC;oCAGR,KAAK,GAAG;wCACN,EAAE,GAAG,EAAE;8CACH,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC;8CAC9B,GAAG;8CACH,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC;8CACjC,GAAG,CAAC;wCACR,KAAK,CAAC;oCAGR,KAAK,GAAG;wCACN,EAAE,GAAG,IAAI,CAAC;wCACV,KAAK,CAAC;oCAER;wCACE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;wCAChD,EAAE,GAAG,EAAE,CAAC;wCACR,KAAK,CAAC;gCACV,CAAC;gCAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAApC,CAAA,EAAsC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,GAAG,iBAAxE,CAAA,EAA0E,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;gCACvE,KAAK,CAAC;4BAGR,KAAK,IAAI;gCACP,KAAK,CAAC;4BAMR,KAAK,IAAI;gCAEC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY;sCACtC,KAAK,GAAG,KAAK,CAAC;gCAEhB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAApC,CAAA,EAAsC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,GAAG,iBAAxE,CAAA,EAA0E,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;gCACvE,KAAK,CAAC;4BAER;gCACE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,yBAAyB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gCACvE,KAAK,CAAC;wBACV,CAAC;wBAED,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC;wBAChC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC;wBAC3B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACnC,CAAC;oBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;wBACxC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;4BACvD,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,EAAE,CAAC;wBACnC,CAAC;wBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;4BAC9C,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,EAAE,CAAC;wBACnC,CAAC;wBAAC,IAAI,CAAC,CAAC;4BACN,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC;wBAC9B,CAAC;oBACH,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,EAAE,CAAC;oBACpC,CAAC;oBACD,KAAK,CAAC;gBAER,KAAK,WAAW,CAAC,MAAM;oBAErB,EAAE,CAAC,CAAC,EAAE,KAAK,iBAArB,CAAA,EAAuB,CAAC,GAAG,IAAI,EAAE,KAAK,iBAAtC,CAAA,EAAwC,CAAC,GAAG,CAAC,CAAC,CAAC;wBACnC,EAAE,CAAC,CAAC,EAAE,KAAK,iBAAvB,CAAA,EAAyB,CAAC,GAAG,CAAC;4BAAC,IAAI,CAAC,SAAS,EAAE,CAAC;wBACpC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACnC,CAAC;oBACD,KAAK,CAAC;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAH;IAOS,MAAT,CAAA,SAAA,CAAA,QAAiB,GAAf,UAAgB,KAAkB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC,CAAH;IAQS,MAAT,CAAA,SAAA,CAAA,SAAkB,GAAhB,UAAiB,MAAc;QAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC;IACjC,CAAC,CAAH;IAQS,MAAT,CAAA,SAAA,CAAA,UAAmB,GAAjB,UAAkB,OAAe;QAC/B,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC;IACnC,CAAC,CAAH;IAOS,MAAT,CAAA,SAAA,CAAA,QAAiB,GAAf,UAAgB,KAAa;QAC3B,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,KAAK,CAAC;IACtC,CAAC,CAAH;IAKS,MAAT,CAAA,SAAA,CAAA,QAAiB,GAAf;QACE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;IACrC,CAAC,CAAH;IAMS,MAAT,CAAA,SAAA,CAAA,aAAsB,GAApB;QACE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC;IAClC,CAAC,CAAH;IAKS,MAAT,CAAA,SAAA,CAAA,YAAqB,GAAnB;QACE,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC,CAAH;IASA,MAAA,CAAA,MAAC,CAAD;AAAA,CArdA,EAqdA,CAAA,CAAC;AArdY,OAAb,CAAA,MAAA,GAAA,MAAA,CAAmB;;;;AD3JnB,IAAM,sBAAsB,GAAG,CAAC,CAAC;AAKjC,IAAK,KAMJ,CAND;AAAA,CAAA,UAAK,KAAK;IACR,KAAF,CAAA,KAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAU,CAAA;IACR,KAAF,CAAA,KAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,GAAA,WAAe,CAAA;IACb,KAAF,CAAA,KAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAW,CAAA;IACT,KAAF,CAAA,KAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAa,CAAA;IACX,KAAF,CAAA,KAAA,CAAA,WAAA,CAAA,GAAA,EAAA,CAAA,GAAA,WAAgB,CAAA;AAChB,CAAC,CAAD,CANK,KAAK,IAMV,CANK,KAAK,GAMV,EAAA,CAAA,CAAA,CAAC;AAAA,CAAC;AAEF,IAAI,UAAU,GAAY,IAAI,CAAC;AAE/B,IAAA,QAAA,GAAA,CAAA;IAME,kBAAoB,SAAoB;QAApB,IAAtB,CAAA,SAA+B,GAAT,SAAS,CAAW;QAJhC,IAAV,CAAA,iBAA2B,GAAmC,EAAE,CAAC;QACvD,IAAV,CAAA,qBAA+B,GAAG,CAAC,CAAC;QAC1B,IAAV,CAAA,sBAAgC,GAAG,IAAI,CAAC;QAKpC,EAAE,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC;YACxB,UAAU,GAAG,eAAe,CAAO,IAAI,CAAC,SAAU,CAAC,QAAQ,CAAC,CAAC;QAC/D,CAAC;IAKH,CAAC;IAQM,QAAT,CAAA,SAAA,CAAA,YAAqB,GAAnB,UAAoB,KAAa,EAAE,GAAW;QAC5C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACxD,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC,CAAH;IAMU,QAAV,CAAA,SAAA,CAAA,YAAsB,GAApB;QAKE,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE,IAAI,sBAAsB,CAAC;QAClH,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACzF,MAAM,CAAC;QACT,CAAC;QAED,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC;QACV,IAAI,GAAG,CAAC;QACR,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAEtC,KAAK,GAAG,CAAC,CAAC;YACV,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC;QAChC,CAAC;QAAC,IAAI,CAAC,CAAC;YAEN,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACxC,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACpC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvD,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;oBAC5C,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC1C,CAAC;gBACD,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;oBACxC,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAH;IAuBU,QAAV,CAAA,SAAA,CAAA,QAAkB,GAAhB,UAAiB,KAAa,EAAE,GAAW;QACzC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC;QAGtH,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC;YAC3C,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACX,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC5B,CAAC,GAAG,KAAK,CAAC;QAEV,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;YACjE,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACrB,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAE/B,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAEzC,QAAQ,CAAC;YACX,CAAC;YACD,GAAG,GAAG,EAAE,CAAC;YAET,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;mBACnE,IAAI,CAAC,SAAS,CAAC,WAAW;mBAC1B,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;gBACpC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACvB,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,CAAC,GAAG,CAAC,CAAC,CAAC;YACT,CAAC;YAED,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC9B,CAAC,GAAG,CAAC,CAAC;YAEN,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAEb,QAAQ,CAAC;gBACX,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClB,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChB,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtB,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;oBACZ,QAAQ,CAAC;gBAEX,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;oBAAC,IAAI,GAAG,CAAC,CAAC,CAAC;gBAEvB,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC;oBAClB,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;wBACpC,GAAG,IAAI,SAAS,CAAC;oBACnB,CAAC;oBACD,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;wBACpC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChB,GAAG,IAAI,8CAA8C,CAAC;wBACxD,CAAC;wBAAC,IAAI,CAAC,CAAC;4BACN,IAAI,UAAU,GAAG,EAAE,CAAC;4BAEpB,EAAE,GAAG,IAAI,GAAG,KAAK,CAAC;4BAClB,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;4BACzB,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;4BAEnB,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gCACvB,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oCAChB,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gCAChC,CAAC;gCAED,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;oCAAC,EAAE,IAAI,CAAC,CAAC;4BACtB,CAAC;4BAED,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gCAC5B,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;4BACrC,CAAC;4BAED,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gCACxB,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;4BACjC,CAAC;4BAGD,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gCAE1B,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gCAGtB,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oCAAC,EAAE,IAAI,CAAC,CAAC;4BACrC,CAAC;4BAED,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gCAC5B,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;4BAClC,CAAC;4BASD,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gCAC1B,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oCACf,EAAE,GAAG,EAAE,CAAC;gCACV,CAAC;gCACD,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oCACf,EAAE,GAAG,CAAC,CAAC;gCACT,CAAC;4BACH,CAAC;4BAED,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;gCACb,UAAU,CAAC,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;4BAC1C,CAAC;4BAED,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;gCACb,UAAU,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;4BACvC,CAAC;4BAED,GAAG,IAAI,OAAO,CAAC;4BACf,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gCACtB,GAAG,IAAI,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;4BACjD,CAAC;4BACD,GAAG,IAAI,GAAG,CAAC;wBACb,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC;oBACnB,GAAG,IAAI,gCAAgC,CAAC;gBAC1C,CAAC;gBACD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACX,KAAK,GAAG;wBACN,GAAG,IAAI,OAAO,CAAC;wBACf,KAAK,CAAC;oBACR,KAAK,GAAG;wBACN,GAAG,IAAI,MAAM,CAAC;wBACd,KAAK,CAAC;oBACR,KAAK,GAAG;wBACN,GAAG,IAAI,MAAM,CAAC;wBACd,KAAK,CAAC;oBACR;wBACE,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;4BACd,GAAG,IAAI,QAAQ,CAAC;wBAClB,CAAC;wBAAC,IAAI,CAAC,CAAC;4BACN,GAAG,IAAI,EAAE,CAAC;wBACZ,CAAC;wBACD,KAAK,CAAC;gBACV,CAAC;gBACD,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC;oBACnB,GAAG,IAAI,SAAS,CAAC;gBACnB,CAAC;gBAED,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;YAED,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;gBACpC,GAAG,IAAI,SAAS,CAAC;YACnB,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC;QAC7C,CAAC;QAED,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAC,CAAC,CAAC;IAC5F,CAAC,CAAH;IAAG,CAAC;IACJ,MAAA,CAAA,QAAC,CAAD;AAAA,CAtQA,EAsQA,CAAA,CAAC;AAtQY,OAAb,CAAA,QAAA,GAAA,QAAA,CAAqB;AA2QrB,yBAAyB,QAAQ;IAC/B,IAAM,IAAI,GAAG,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,IAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,EAAE,CAAC,SAAS,GAAG,aAAa,CAAC;IAC7B,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACrB,IAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;IAC1B,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAC7B,IAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;IAC1B,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;;;;ADpSD,IAAA,QAAA,GAAA,CAAA;IAYE,kBACU,QAAmB,EACnB,eAA4B,EAC5B,UAAuB,EACvB,WAAwB;QAHxB,IAAZ,CAAA,QAAoB,GAAR,QAAQ,CAAW;QACnB,IAAZ,CAAA,eAA2B,GAAf,eAAe,CAAa;QAC5B,IAAZ,CAAA,UAAsB,GAAV,UAAU,CAAa;QACvB,IAAZ,CAAA,WAAuB,GAAX,WAAW,CAAa;QAEhC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,wBAAwB,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,0BAA0B,GAAG,CAAC,CAAC;QAEpC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1E,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAQO,QAAV,CAAA,SAAA,CAAA,OAAiB,GAAf;QACE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAChC,IAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,gBAAgB,CAAC;YAC3E,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACrB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;gBAChD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;gBACvE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;YAC/E,CAAC;YACD,IAAM,qBAAqB,GAAG,IAAI,CAAC,0BAA0B,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACrF,EAAE,CAAC,CAAC,gBAAgB,IAAI,qBAAqB,CAAC,CAAC,CAAC;gBAC9C,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACrD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;YAC1F,CAAC;YACD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,IAAI,CAAC;QAClG,CAAC;IACH,CAAC,CAAH;IAKS,QAAT,CAAA,SAAA,CAAA,cAAuB,GAArB;QACE,EAAE,CAAC,CAAC,IAAI,CAAC,wBAAwB,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAEjE,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;YAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,0BAA0B,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAElE,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;QAAC,IAAI,CAAC,CAAC;YAEN,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;QAGD,IAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC9D,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7C,CAAC;IACH,CAAC,CAAH;IAOU,QAAV,CAAA,SAAA,CAAA,QAAkB,GAAhB,UAAiB,EAAS;QACxB,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAClF,IAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC,CAAH;IAQS,QAAT,CAAA,SAAA,CAAA,OAAgB,GAAd,UAAe,EAAc;QAC3B,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;YAEpB,MAAM,CAAC;QACT,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;YAC/C,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACrC,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;YACtD,UAAU,GAAG,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,SAAS,IAAI,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC;QAEzD,EAAE,CAAC,cAAc,EAAE,CAAC;IACtB,CAAC,CAAH;IAAG,CAAC;IACJ,MAAA,CAAA,QAAC,CAAD;AAAA,CA9GA,EA8GA,CAAA,CAAC;AA9GY,OAAb,CAAA,QAAA,GAAA,QAAA,CAAqB;;;;ADcrB,iCAAwC,IAAY;IAClD,IAAI,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,EAC/B,gBAAgB,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAC3C,oBAAoB,GAAG,IAAI,MAAM,CAAC,gBAAgB,EAAE,GAAG,CAAC,EACxD,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI;QAGjD,IAAI,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAEnF,MAAM,CAAC,aAAa,CAAC;IACvB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAElB,MAAM,CAAC,aAAa,CAAC;AACvB,CAAC;AAbD,OAAA,CAAA,uBAAA,GAAA,uBAAA,CAaC;AAMD,qBAA4B,EAAkB,EAAE,IAAe;IAG7D,IAAI,UAAU,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,EAC7C,IAAI,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAE/C,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,EAAE,CAAC,cAAc,EAAE,CAAC;AACtB,CAAC;AAbD,OAAA,CAAA,WAAA,GAAA,WAAA,CAaC;AAOD,sBAA6B,EAAkB,EAAE,IAAe;IAC9D,EAAE,CAAC,eAAe,EAAE,CAAC;IAErB,IAAI,IAAY,CAAC;IAEjB,IAAI,aAAa,GAAG,UAAS,IAAI;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACxB,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;YACzB,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5C,aAAa,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,EAAE,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;YACrB,IAAI,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC9C,aAAa,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC;AAtBD,OAAA,CAAA,YAAA,GAAA,YAAA,CAsBC;AAeD,2BAAkC,EAAc,EAAE,IAAe;IAC/D,IAAI,CAAC,GAAG,QAAQ,CAAC,YAAY,EAAE,EAC3B,YAAY,GAAG,uBAAuB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,EACpD,kBAAkB,GAAG,KAAK,EAC1B,CAAC,GAAG,EAAE,CAAC,OAAO,EACd,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;IAEnB,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EACnB,EAAE,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC;QAE5B,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAEjB,kBAAkB,GAAG,CACnB,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;gBACnC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CACpC,CAAC;YAEF,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;gBACvB,KAAK,CAAC;YACR,CAAC;QACH,CAAC;QAKD,EAAE,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;YACvD,kBAAkB,GAAG,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;IAGD,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;QAC3C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAGtB,UAAU,CAAC;YACT,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACpC,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;AACH,CAAC;AApDD,OAAA,CAAA,iBAAA,GAAA,iBAAA,CAoDC;;;;ADnJD,IAAA,SAAA,GAAA,OAAA,CAAA,WAAA,CAAA,CAAqC;AAErC,IAAM,MAAM,GAAG,CAAC,OAAO,SAAS,KAAK,WAAW,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AACjE,IAAM,SAAS,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC;AAC1D,IAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC;AAE3C,OAAb,CAAa,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAC5C,OAAb,CAAa,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAKzE,OAAb,CAAa,KAAK,GAAG,SAArB,CAAA,QAA6B,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC1E,OAAb,CAAa,MAAM,GAAG,QAAQ,KAAK,MAAM,CAAC;AAC7B,OAAb,CAAa,QAAQ,GAAG,QAAQ,KAAK,QAAQ,CAAC;AACjC,OAAb,CAAa,WAAW,GAAG,SAA3B,CAAA,QAAmC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;;;;;;;;;;;ADhBtF,IAAA,iBAAA,GAAA,OAAA,CAAA,oBAAA,CAAA,CAAkD;AAKlD,IAAA,WAAA,GAAA,CAAA,UAAA,MAAA;IAAiC,SAAjC,CAAA,WAAA,EAAA,MAAA,CAAA,CAA6C;IAM3C,qBAAY,aAA0B;QAAtC,IAAF,KAAA,GACI,MADJ,CAAA,IAAA,CAAA,IAAA,CACW,IADX,IAAA,CAGG;QADC,KAAI,CAAC,cAAc,GAAG,aAAa,CAAC;;IACtC,CAAC;IAED,MAAF,CAAA,cAAA,CAAa,WAAb,CAAA,SAAA,EAAA,OAAkB,EAAlB;QAAA,GAAA,EAAE;YACE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;;;KAAH,CAAA,CAAG;IAED,MAAF,CAAA,cAAA,CAAa,WAAb,CAAA,SAAA,EAAA,QAAmB,EAAnB;QAAA,GAAA,EAAE;YACE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;;;KAAH,CAAA,CAAG;IAEM,WAAT,CAAA,SAAA,CAAA,OAAgB,GAAd;QAAA,IAAF,KAAA,GAAA,IAAA,CAcG;QAbC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YACtD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;YACrC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;YAC5C,IAAI,CAAC,eAAe,CAAC,WAAW,GAAG,GAAG,CAAC;YACvC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAGtD,UAAU,CAAC,cAAM,MAAvB,CAAuB,KAAI,CAAC,UAAU,EAAE,CAAxC,CAAuB,CAAiB,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;IACH,CAAC,CAAH;IAEU,WAAV,CAAA,SAAA,CAAA,UAAoB,GAAlB;QACE,IAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,qBAAqB,EAAE,CAAC;QAG9D,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,CAAC;QACT,CAAC;QACD,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAH;IACA,MAAA,CAAA,WAAC,CAAD;AAAA,CAhDA,CAAiC,iBAgDjC,CAAA,YAhD6C,CAgD7C,CAAA,CAAC;AAhDY,OAAb,CAAA,WAAA,GAAA,WAAA,CAAwB;;;;ADJxB,IAAA,YAAA,GAAA,CAAA;IAKE,sBAAY,SAAiB;QAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAI,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,MAAF,CAAA,cAAA,CAAa,YAAb,CAAA,SAAA,EAAA,WAAsB,EAAtB;QAAA,GAAA,EAAE;YACE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAC5B,CAAC;QAEH,GAAA,EAAE,UAAqB,YAAoB;YAGvC,IAAI,QAAQ,GAAG,IAAI,KAAK,CAAI,YAAY,CAAC,CAAC;YAC1C,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7D,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;;;KAXH,CAAA,CAAG;IAaD,MAAF,CAAA,cAAA,CAAa,YAAb,CAAA,SAAA,EAAA,QAAmB,EAAnB;QAAA,GAAA,EAAE;YACE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QAEH,GAAA,EAAE,UAAkB,SAAiB;YACjC,EAAE,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC7B,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC9C,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;gBAC7B,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QAC3B,CAAC;;;KATH,CAAA,CAAG;IAWD,MAAF,CAAA,cAAA,CAAa,YAAb,CAAA,SAAA,EAAA,SAAoB,EAApB;QAAA,GAAA,EAAE;YACE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QAC7B,CAAC;;;KAAH,CAAA,CAAG;IAUM,YAAT,CAAA,SAAA,CAAA,GAAY,GAAV,UAAW,KAAa;QACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAClD,CAAC,CAAH;IAUS,YAAT,CAAA,SAAA,CAAA,GAAY,GAAV,UAAW,KAAa,EAAE,KAAQ;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC;IACnD,CAAC,CAAH;IAOS,YAAT,CAAA,SAAA,CAAA,IAAa,GAAX,UAAY,KAAQ;QAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC;QACxD,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACpC,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;gBACxC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC,CAAH;IAMS,YAAT,CAAA,SAAA,CAAA,GAAY,GAAV;QACE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAH;IAWS,YAAT,CAAA,SAAA,CAAA,MAAe,GAAb,UAAc,KAAa,EAAE,WAAmB;QAAE,IAApD,KAAA,GAAA,EAAA,CAAiE;QAAjE,GAAA,CAAA,CAAoD,IAApD,EAAA,GAAA,CAAiE,EAAb,EAApD,GAAA,SAAA,CAAA,MAAiE,EAAb,EAApD,EAAiE,EAAjE,CAAA;YAAoD,KAApD,CAAA,EAAA,GAAA,CAAA,CAAA,GAAA,SAAA,CAAA,EAAA,CAAA,CAAiE;;QAC7D,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAChB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;YAC5F,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC;QAC9B,CAAC;QACD,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC1B,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7F,CAAC;YACD,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1D,CAAC;YAED,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;gBACjD,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;gBACnE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;YAChC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC,CAAH;IAMS,YAAT,CAAA,SAAA,CAAA,SAAkB,GAAhB,UAAiB,KAAa;QAC5B,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACzB,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC;QAC1B,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACxB,CAAC,CAAH;IAES,YAAT,CAAA,SAAA,CAAA,aAAsB,GAApB,UAAqB,KAAa,EAAE,KAAa,EAAE,MAAc;QAC/D,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,MAAM,CAAC;QACT,CAAC;QACD,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,EAAE,CAAC,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;QAED,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,IAAM,YAAY,GAAG,CAAC,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAC7D,EAAE,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;gBACrB,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC;gBAC7B,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;oBACrC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;IACH,CAAC,CAAH;IAQU,YAAV,CAAA,SAAA,CAAA,eAAyB,GAAvB,UAAwB,KAAa;QACnC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACrD,CAAC,CAAH;IACA,MAAA,CAAA,YAAC,CAAD;AAAA,CAhLA,EAgLA,CAAA,CAAC;AAhLY,OAAb,CAAA,YAAA,GAAA,YAAA,CAAyB;;;;ADKzB,kBAAyB,GAAU,EAAE,EAAO;IAC1C,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAFD,OAAA,CAAA,QAAA,GAAA,QAAA,CAEC;AAAA,CAAC;;;;ADDF,IAAA,mBAAA,GAAA,OAAA,CAAA,qBAAA,CAAA,CAAwD;AACxD,IAAA,cAAA,GAAA,OAAA,CAAA,gBAAA,CAAA,CAA8C;AAC9C,IAAA,UAAA,GAAA,OAAA,CAAA,YAAA,CAAA,CAAsC;AACtC,IAAA,WAAA,GAAA,OAAA,CAAA,sBAAA,CAAA,CAAoF;AACpF,IAAA,cAAA,GAAA,OAAA,CAAA,sBAAA,CAAA,CAAoD;AACpD,IAAA,iBAAA,GAAA,OAAA,CAAA,mBAAA,CAAA,CAAuC;AACvC,IAAA,cAAA,GAAA,OAAA,CAAA,gBAAA,CAAA,CAA8C;AAC9C,IAAA,QAAA,GAAA,OAAA,CAAA,UAAA,CAAA,CAAkC;AAClC,IAAA,UAAA,GAAA,OAAA,CAAA,YAAA,CAAA,CAAsC;AACtC,IAAA,aAAA,GAAA,OAAA,CAAA,qBAAA,CAAA,CAAkD;AAClD,IAAA,OAAA,GAAA,OAAA,CAAA,iBAAA,CAAA,CAA2C;AAgB3C,IAAI,QAAQ,GAAG,CAAC,OAAO,MAAM,IAAI,WAAW,CAAC,GAAG,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;AAOvE,IAAI,4BAA4B,GAAG,CAAC,CAAC;AAMrC,IAAI,gBAAgB,GAAG,GAAG,CAAC;AAkB3B,kBAAkB,OAAO;IACvB,IAAI,IAAI,GAAG,IAAI,CAAC;IAEhB,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,QAAQ,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE9B,cAAF,CAAA,YAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAExB,EAAE,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC;QAChC,OAAO,GAAG;YACR,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;YAClB,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;YAClB,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;SACtB,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IAGxB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,UAAS,GAAG;QACjD,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAErC,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;QAChC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CACjD,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CACpC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAIvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,CAC9C,QAAQ,GAAG,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAC3D,CAAC;IAEF,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEvC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAMD,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IAKf,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IAKf,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAKX,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAEX,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IACrB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC;IAChB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACnB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAGjC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IAC/B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IAGnB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChB,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC;IAGvB,IAAI,CAAC,UAAU,CAAC;IAChB,IAAI,CAAC,QAAQ,CAAC;IACd,IAAI,CAAC,UAAU,CAAC;IAChB,IAAI,CAAC,UAAU,CAAC;IAChB,IAAI,CAAC,WAAW,CAAC;IACjB,IAAI,CAAC,WAAW,CAAC;IACjB,IAAI,CAAC,SAAS,CAAC;IACf,IAAI,CAAC,QAAQ,CAAC;IACd,IAAI,CAAC,QAAQ,CAAC;IACd,IAAI,CAAC,UAAU,CAAC;IAGhB,IAAI,CAAC,OAAO,CAAC;IACb,IAAI,CAAC,QAAQ,CAAC;IACd,IAAI,CAAC,YAAY,CAAC;IAClB,IAAI,CAAC,UAAU,CAAC;IAChB,IAAI,CAAC,MAAM,CAAC;IACZ,IAAI,CAAC,MAAM,CAAC;IACZ,IAAI,CAAC,SAAS,CAAC;IAGf,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IAErB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAE5B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACjB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACjB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IAElB,IAAI,CAAC,YAAY,GAAG,IAAI,cAA1B,CAAA,YAAsC,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,QAApB,CAAA,MAA0B,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAElD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;IAGtC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAQ7B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IAG/B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAG1B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;IAMzB,IAAI,CAAC,KAAK,GAAG,IAAI,cAAnB,CAAA,YAA+B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IAClB,OAAO,CAAC,EAAE,EAAE,CAAC;QACX,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC;IACV,IAAI,CAAC,UAAU,EAAE,CAAC;IAGlB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;AAC7B,CAAC;AAED,QAAQ,CAAC,QAAQ,EAAE,cAAnB,CAAA,YAA+B,CAAC,CAAC;AAKjC,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG;IAE7B,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;AAC1D,CAAC,CAAC;AAOF,QAAQ,CAAC,WAAW,GAAG;IAErB,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IAET,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC;AAIF,QAAQ,CAAC,MAAM,GAAG,CAAC;IACjB,IAAI,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,EACvC,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EACxC,CAAC,CAAC;IAGJ,CAAC,GAAG,CAAC,CAAC;IACN,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACpB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IAGD,CAAC,GAAG,CAAC,CAAC;IACN,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACf,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACf,CAAC;IAED,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,aAAa,CAAC;QACZ,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACnB,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,CAAC,MAAM,CAAC;AAChB,CAAC,CAAC,EAAE,CAAC;AAEL,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;AAE3C,QAAQ,CAAC,OAAO,GAAG,CAAC;IAClB,IAAI,GAAG,GAAG,EAAE,EACV,MAAM,GAAG,QAAQ,CAAC,MAAM,EACxB,CAAC,GAAG,CAAC,EACL,KAAK,CAAC;IAER,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACpB,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,GAAG,CAAC,IAAI,CAAC;YACP,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI;YACpB,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI;YACnB,KAAK,GAAG,IAAI;SACb,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,GAAG,CAAC;AACb,CAAC,CAAC,EAAE,CAAC;AAML,QAAQ,CAAC,QAAQ,GAAG;IAClB,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IAClB,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,OAAO;IACpB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,KAAK;IACjB,KAAK,EAAE,KAAK;IACZ,YAAY,EAAE,KAAK;IACnB,YAAY,EAAE,KAAK;IACnB,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE,CAAC;CAGhB,CAAC;AAEF,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC;AAEtB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;AAEtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAS,GAAG;IACxC,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAKH,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG;IACzB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAS,GAAG,EAAE,KAAK;IAChD,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAS,GAAG,EAAE,KAAK;IAChD,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACZ,KAAK,YAAY;YACf,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;gBAChC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;oBAC9B,IAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;oBAC/C,IAAM,YAAY,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC;oBACrD,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBACnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;oBACpD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;oBACpD,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;wBACjB,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;gBAC7B,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;YACjC,CAAC;YACD,KAAK,CAAC;IACV,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAClB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC1B,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACZ,KAAK,aAAa;YAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YAAC,KAAK,CAAC;QACtF,KAAK,aAAa;YAEhB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,8BAA8B,EAAE,KAAK,KAAK,WAAW,CAAC,CAAC;YACrF,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,wBAAwB,EAAE,KAAK,KAAK,KAAK,CAAC,CAAC;YACzE,KAAK,CAAC;QACR,KAAK,cAAc;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YAAC,KAAK,CAAC;IAChD,CAAC;AACH,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,GAAG,UAAU,IAAI;IACjC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE;QACrC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,IAAI,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG;IACxB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC9B,CAAC,CAAC;AAOF,QAAQ,CAAC,QAAQ,GAAG,UAAU,IAAI;IAChC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE;QACpC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,IAAI,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG;IAC9B,IAAI,IAAI,GAAG,IAAI,CAAC;IAEhB,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAGxB,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE;QACnC,WAAJ,CAAA,WAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE;QACrC,WAAJ,CAAA,YAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE;QACpC,WAAJ,CAAA,YAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,kCAAmC,EAAE;QACnC,WAAJ,CAAA,iBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3B,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE;YACxC,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;gBACnB,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,wBAAwB,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC,CAAC;AAKF,QAAQ,CAAC,QAAQ,GAAG,UAAS,IAAI;IAC/B,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,UAAS,EAAE;QACrC,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC;YACnC,MAAM,CAAC;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,UAAS,EAAE;QACtC,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC;YACnC,MAAM,CAAC;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,UAAS,EAAE;QACnC,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAS,EAAE;QACtC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAS,EAAE;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAElB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,EAAE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC5G,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,EAAE,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC9G,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACxG,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACpG,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAU,GAAG;IAC1C,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC;QAC3B,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC;AACb,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,UAAS,MAAM;IACvC,IAAI,IAAI,GAAC,IAAI,EAAE,CAAC,GAAC,CAAC,EAAE,GAAG,CAAC;IAExB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;IAEpC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAGD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC;IACrD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;IAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAG1D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAE9E,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAA;IACzB,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAEzC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/C,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC3D,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAI1D,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IAInB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAEpD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE;QACtC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEhD,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACvD,IAAI,CAAC,iBAAiB,GAAG,IAAI,mBAA/B,CAAA,iBAAgD,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAC1F,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAEvD,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAE5D,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEtC,IAAI,CAAC,WAAW,GAAG,IAAI,aAAzB,CAAA,WAAoC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACzD,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,iBAAiB,EAAE;QACrC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAE3B,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAtB,CAAA,QAA8B,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAtB,CAAA,QAA8B,CAAC,IAAI,CAAC,CAAC;IAGnC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAI/B,IAAI,CAAC,UAAU,EAAE,CAAC;IAGlB,IAAI,CAAC,KAAK,EAAE,CAAC;IAEb,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE;QACxB,IAAI,SAAS,GAAG,QAAQ,CAAC,YAAY,EAAE,EACnC,SAAS,GAAG,SAAS,CAAC,WAAW,EACjC,OAAO,GAAG,OAAO,SAAS,IAAI,SAAS,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC;QACrF,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAIH,IAAI,CAAC,SAAS,EAAE,CAAC;IAOjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,GAAG,UAAS,KAAK,EAAE,QAAQ;IAC3C,EAAE,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC;QAE9D,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC;IACpD,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC;QAEvC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACnF,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,iBAAiB,GAAG;IACrC,IAAI,CAAC,oBAAoB,CAAC,WAAW,GAAG,yBAAyB,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;AAC5G,CAAC,CAAA;AAYD,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG;IAC7B,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE,CAAC;IAKjD,oBAAoB,EAAE;QACpB,IAAI,MAAM,EACR,GAAG,CAAC;QAGN,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAGvB,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QACpB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAAC,MAAM,CAAC;QAEjB,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEvB,MAAM,CAAC,CAAC,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YACnC,KAAK,WAAW;gBACd,OAAO,GAAG,MAAM,CAAC;gBACjB,KAAK,CAAC;YACR,KAAK,SAAS;gBAGZ,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CAAC;YACR,KAAK,OAAO;gBAIV,KAAK,CAAC;QACV,CAAC;IACH,CAAC;IAID,kBAAkB,EAAE;QAClB,IAAI,MAAM,GAAG,OAAO,EAClB,GAAG,CAAC;QAEN,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QACpB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAAC,MAAM,CAAC;QAIjB,MAAM,IAAI,EAAE,CAAC;QAEb,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzB,CAAC;IAID,gBAAgB,IAAI,EAAE,EAAE;QACtB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACnB,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACpC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC;gBAAC,EAAE,GAAG,GAAG,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChB,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC;oBAAC,EAAE,GAAG,IAAI,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAQD,mBAAmB,MAAM,EAAE,GAAG;QAO5B,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAGpB,MAAM,IAAI,CAAC,CAAC;YACZ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,IAAI,IAAI,GAAG,iBAAjB,CAAA,EAAmB,CAAC,GAAG,GAAG,KAAK,CAAC;YAC1B,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,IAAI,IAAI,GAAG,CAAC;YAC9B,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,IAAI,IAAI,GAAG,CAAC;YACnC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,IAAI,IAAI,GAAG,CAAC;YACnC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,MAAM,CAAC;YAC9B,IAAI;gBAAC,IAAI,IAAI,GAAG,CAAC;YACjB,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,MAAM,CAAC;QACT,CAAC;QAED,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAEpB,MAAM,IAAI,CAAC,CAAC;YACZ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,MAAM,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,MAAM,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,MAAM,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;gBAAC,MAAM,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,GAAG,GAAG;kBACV,MAAM;kBACN,GAAG;kBACH,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;kBACtB,GAAG;kBACH,GAAG,CAAC,CAAC;kBACL,GAAG;kBACH,GAAG,CAAC,CAAC;kBACL,GAAG;kBACH,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;kBACf,IAAI,CAAC,CAAC;YAClB,MAAM,CAAC;QACT,CAAC;QAED,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACpB,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,GAAG,CAAC,CAAC,EAAE,CAAC;YACR,GAAG,CAAC,CAAC,EAAE,CAAC;YACR,IAAI,CAAC,IAAI,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YACnE,MAAM,CAAC;QACT,CAAC;QAED,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClB,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,GAAG,IAAI;kBACX,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;kBAClD,GAAG;kBACH,GAAG,CAAC,CAAC;kBACL,GAAG;kBACH,GAAG,CAAC,CAAC;kBACL,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC;QACT,CAAC;QAED,IAAI,IAAI,GAAG,EAAE,CAAC;QAEd,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,CAAC,IAAI,CAAC,iBAAd,CAAA,EAAgB,CAAC,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,mBAAmB,EAAE;QACnB,IAAI,MAAM,EACR,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,GAAG,CAAC;QASN,MAAM,CAAC,CAAC,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YACnC,KAAK,WAAW;gBACd,MAAM,GAAG,EAAE,CAAC,MAAM,IAAI,IAAI;sBACtB,CAAC,EAAE,CAAC,MAAM;sBACZ,EAAE,CAAC,KAAK,IAAI,IAAI;0BACd,EAAE,CAAC,KAAK,GAAG,CAAC;0BACd,IAAI,CAAC;gBAEP,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;oBACxB,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBACxD,CAAC;gBACD,KAAK,CAAC;YACR,KAAK,SAAS;gBACZ,MAAM,GAAG,CAAC,CAAC;gBACX,KAAK,CAAC;YACR,KAAK,gBAAgB;gBACnB,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC;sBAClB,EAAE;sBACJ,EAAE,CAAC;gBACL,KAAK,CAAC;YACR,KAAK,OAAO;gBACV,MAAM,GAAG,EAAE,CAAC,WAAW,GAAG,CAAC;sBACvB,EAAE;sBACJ,EAAE,CAAC;gBACL,KAAK,CAAC;QACV,CAAC;QAID,KAAK,GAAG,EAAE,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,GAAG,EAAE,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,GAAG,EAAE,CAAC,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3B,GAAG,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;QAG1B,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAEpB,GAAG,IAAI,IAAI,CAAC;QACd,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAC7B,GAAG,GAAG,CAAC,CAAC;QACV,CAAC;QAGD,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QAEpC,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IAGD,mBAAmB,EAAE;QACnB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAGnB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC;YAAC,MAAM,CAAC;QAE7B,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;QACb,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;QACb,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAIlB,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;YAClD,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC;YACnB,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC;YAClB,EAAE,GAAG,cAAc,IAAI,EAAE;kBACrB,EAAE,CAAC,YAAY;kBACjB,EAAE,CAAC,UAAU,CAAC;QAClB,CAAC;QAGD,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7B,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QAC9B,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAInC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC,GAAG,CAAC,CAAC;QACjB,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;YAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACjC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC,GAAG,CAAC,CAAC;QACjB,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;YAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QAIjC,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,IAAI,EAAE,CAAC;QAER,MAAM,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;YACJ,IAAI,EAAE,OAAO;SACd,CAAC;IACJ,CAAC;IAED,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,UAAS,EAAE;QAC7B,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAAC,MAAM,CAAC;QAG9B,UAAU,CAAC,EAAE,CAAC,CAAC;QAGf,IAAI,CAAC,KAAK,EAAE,CAAC;QAIb,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACpB,EAAE,CAAC,YAAY,GAAG,SAAS,CAAC;YAC5B,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QAGD,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAG/D,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACnB,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE;gBACzC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACf,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;oBAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAChE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAMH,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,UAAS,EAAE;QACzB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAAC,MAAM,CAAC;QAC9B,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ;eACV,IAAI,CAAC,UAAU;eACf,IAAI,CAAC,UAAU,CAAC;YAAC,MAAM,CAAC;QAC/B,UAAU,CAAC,EAAE,CAAC,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAIH,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,UAAS,EAAE;QACzB,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,OAAO,GAAG;IAC3B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACtB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACtB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC,OAAO,GAAG,cAAY,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,GAAG,cAAY,CAAC,CAAC;IAC3B,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;AAEH,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,OAAO,GAAG,UAAS,KAAK,EAAE,GAAG;IAC9C,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;AACH,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG;IAC9B,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG;IAC1B,IAAI,GAAG,CAAC;IAGR,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;IAGb,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC1B,CAAC;IAGD,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IAGjC,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;IAEzC,EAAE,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAE9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACpC,CAAC;IAAC,IAAI,CAAC,CAAC;QAEN,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAGD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAQpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC;AASF,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG,UAAS,IAAI,EAAE,mBAAmB;IAChE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;IAEnB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC1B,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG,UAAS,SAAS;IACjD,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAA;AAKD,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG;IAC/B,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAA;AAKD,QAAQ,CAAC,SAAS,CAAC,cAAc,GAAG;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC,CAAA;AAMD,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG,UAAS,IAAI;IACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAK5B,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,4BAA4B,CAAC,CAAC,CAAC;QAGtH,IAAI,CAAC,IAAI,CAAC,iBAAd,CAAA,EAAgB,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChC,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAEzD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAE5B,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,UAAU,CAAC;YACT,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAA;AAED,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG;IAC9B,IAAI,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC9D,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC;QAIhE,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;YACvF,IAAI,CAAC,IAAI,CAAC,iBAAhB,CAAA,EAAkB,CAAC,GAAG,CAAC,CAAC;YAClB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;QAEzB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IACD,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAEhC,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,UAAU,CAAC;YACT,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,OAAO,GAAG,UAAS,IAAI;IACxC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;AAC5B,CAAC,CAAC;AAUF,QAAQ,CAAC,SAAS,CAAC,0BAA0B,GAAG,UAAS,oBAAoB;IAC3E,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;AACnD,CAAC,CAAA;AAQD,QAAQ,CAAC,SAAS,CAAC,OAAO,GAAG,UAAS,EAAE;IACtC,EAAE,CAAC,CAAC,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC;QACD,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAEhD,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,iBAArB,CAAA,EAAuB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,iBAA5B,CAAA,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,EAAE,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAElB,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,EAAE,CAAC;IAClB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEzB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAC;AASF,QAAQ,CAAC,SAAS,CAAC,yBAAyB,GAAG,UAAS,EAAE;IACxD,IAAI,MAAM,GAAG;QAGX,MAAM,EAAE,KAAK;QAEb,GAAG,EAAE,SAAS;QAEd,UAAU,EAAE,SAAS;KACtB,CAAC;IACF,IAAI,SAAS,GAAG,EAAE,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC;IACtF,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACnB,KAAK,CAAC;YAEJ,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChB,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,EAAE,CAAC;gBACnB,KAAK,CAAC;YACR,CAAC;YACD,MAAM,CAAC,GAAG,GAAG,iBAAnB,CAAA,EAAqB,CAAC,GAAG,CAAC;YACpB,KAAK,CAAC;QACR,KAAK,CAAC;YAEJ,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChB,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;gBAC3B,KAAK,CAAC;YACR,CAAC;YACD,MAAM,CAAC,GAAG,GAAG,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,MAAM,CAAC,GAAG,GAAG,iBAAnB,CAAA,EAAqB,CAAC,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,MAAM,CAAC,GAAG,GAAG,iBAAnB,CAAA,EAAqB,CAAC,GAAG,CAAC;YACpB,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAIpD,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,iBAA1B,CAAA,EAA4B,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;oBACnC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,iBAA9C,CAAA,EAAgD,CAAC,GAAG,GAAG,GAAG,GAAG,iBAA7D,CAAA,EAA+D,CAAC,GAAG,GAAG,OAAO,CAAC;gBACtE,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAClC,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAIpD,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,iBAA1B,CAAA,EAA4B,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;oBACnC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,iBAA9C,CAAA,EAAgD,CAAC,GAAG,GAAG,GAAG,GAAG,iBAA7D,CAAA,EAA+D,CAAC,GAAG,GAAG,OAAO,CAAC;gBACtE,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAClC,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAGpD,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,iBAA1B,CAAA,EAA4B,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;oBACnC,MAAM,CAAC,GAAG,GAAG,iBAAvB,CAAA,EAAyB,CAAC,GAAG,GAAG,OAAO,CAAC;gBAChC,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAClC,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAGpD,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,iBAA1B,CAAA,EAA4B,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;oBACnC,MAAM,CAAC,GAAG,GAAG,iBAAvB,CAAA,EAAyB,CAAC,GAAG,GAAG,OAAO,CAAC;gBAChC,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAClC,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;gBAGhC,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC;gBACZ,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;gBAC9B,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,IAAI;gBACF,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,SAAS,CAAC;gBACZ,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;gBAC9B,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,IAAI;gBACF,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChB,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YACvC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,EAAE;YAEL,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YACpC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YAEN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACtD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,IAAI,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR,KAAK,GAAG;YACN,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACd,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,MAAM,CAAC,GAAG,GAAG,iBAArB,CAAA,EAAuB,CAAC,GAAG,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC;QACR;YAEE,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC5D,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;oBACzC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;gBACpD,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;oBAE7B,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;gBACtC,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;oBAEhD,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;gBACzD,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;oBAE7B,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;gBACxC,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC;oBAE9B,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC;oBAE9B,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC;oBAE9B,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;gBAE1E,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;oBACzC,MAAM,CAAC,GAAG,GAAG,iBAAvB,CAAA,EAAyB,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;gBAC7D,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC9B,MAAM,CAAC,GAAG,GAAG,iBAAvB,CAAA,EAAyB,CAAC,GAAG,GAAG,GAAG,CAAC;gBAC5B,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;oBAChD,MAAM,CAAC,GAAG,GAAG,iBAAvB,CAAA,EAAyB,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YACD,KAAK,CAAC;IACV,CAAC;IAED,MAAM,CAAC,MAAM,CAAC;AAChB,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAS,CAAC;IACvC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG,UAAS,CAAC,EAAE,OAAO;IAClD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAC3B,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,QAAQ,GAAG,UAAS,EAAE;IACvC,IAAI,GAAG,CAAC;IAER,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAEhB,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChB,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC;IACpB,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;QAC5B,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC;IACnB,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/C,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC;IACjB,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CACV,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,CACxE,CAAC,CAAC,CAAC;QACF,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAE/B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC1B,IAAI,CAAC,UAAU,EAAE,CAAC;IAClB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAElB,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,UAAS,IAAI;IACrC,IAAI,IAAI,GAAG,IAAI,CAAC;IAEhB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAChB,UAAU,CAAC;YACT,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAClB,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAED,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;AACrB,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG;IACxB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAAC,MAAM,CAAC;IAC7B,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;IACzC,UAAU,CAAC;QACT,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;IACtC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAAC,IAAI,CAAC,KAAK,EAAE,CAAC;AACnC,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,GAAG,GAAG;IACvB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAAC,MAAM,CAAC;IACxB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;QAAC,MAAM,CAAC;IAC/D,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC7D,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG;IACzB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAAC,MAAM,CAAC;IACxB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QAAC,MAAM,CAAC;IACjE,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC/D,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,UAAS,CAAC,EAAE,CAAC;IACvC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC;IACT,CAAC;IAED,IAAI,IAAI,EACN,EAAE,EACF,CAAC,EACD,CAAC,EACD,EAAE,EACF,MAAM,CAAC;IAET,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC;IACT,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC,GAAG,CAAC,CAAC;IACjB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC,GAAG,CAAC,CAAC;IAGjB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACd,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACV,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACd,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAG3B,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACd,MAAM,GAAG,CAAC,CAAC;IACX,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACV,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YAEf,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBACvC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;oBAG5E,IAAI,CAAC,KAAK,EAAE,CAAC;oBACb,MAAM,EAAE,CAAA;oBACR,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;wBAEnB,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,CAAC;gBACH,CAAC;gBAAC,IAAI,CAAC,CAAC;oBAGN,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YACD,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACf,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBACvC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAEhD,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;gBACnB,CAAC;gBAAC,IAAI,CAAC,CAAC;oBAEN,IAAI,CAAC,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,CAAC;YACH,CAAC;YACD,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC7B,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC3B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAAC,QAAQ,CAAC;gBAClB,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IAGd,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IACD,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACX,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC;IACnB,CAAC;IAED,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACnB,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC;IAE1B,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAE3B,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAE/B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IAEnB,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAC,CAAC,CAAC;AAC1D,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG,UAAS,CAAC;IACzC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;QAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IACjD,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;QAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;AAO/C,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,QAAQ,GAAG;IAC5B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;AAClC,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG,UAAS,CAAC;IACxC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACd,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,CAAC,GAAG,CAAC,CAAC;IACR,CAAC;IAED,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACtB,CAAC;AACH,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,QAAQ,GAAG,UAAS,CAAC;IACtC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAC,CAAC;IACjC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI;UACjB,IAAI,CAAC,IAAI,GAAG,CAAC;UACf,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAClB,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,QAAQ,GAAG,UAAS,CAAC;IACtC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;QAAC,CAAC;IACzC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI;UACjB,IAAI,CAAC,IAAI,GAAG,CAAC;UACf,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAClB,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG,UAAS,CAAC,EAAE,CAAC;IAC3C,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC1C,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACV,MAAM,CAAC;IACT,CAAC;IACD,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACpC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC;AASF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAS,CAAC,EAAE,CAAC;IAC1C,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC1C,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACV,MAAM,CAAC;IACT,CAAC;IACD,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC;IACJ,OAAO,CAAC,EAAE,EAAE,CAAC;QACX,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC;AAKF,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG;IACzB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAErC,MAAM,CAAC;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACf,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACf,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACX,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAS,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,UAAS,GAAG;IACzC,IAAI,IAAI,GAAG,GAAG;UACZ,IAAI,CAAC,SAAS,EAAE;UAChB,IAAI,CAAC,OAAO,CAAC;IAEf,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EACrB,IAAI,GAAG,EAAE,EACT,CAAC,GAAG,CAAC,CAAC;IAER,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IAED,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,EAAE,GAAG,UAAS,GAAG;IAClC,MAAM,CAAC,GAAG;UACN,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;UAC5B,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,EAAE,GAAG,UAAS,IAAI;IACnC,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;IACzB,MAAM,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,OAAO,GAAG,UAAS,IAAI;IAExC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC;IACT,CAAC;IAGD,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC;AAOF,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG,UAAS,KAAK;IAO7C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC5B,CAAC,CAAC;AAUF,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG;IACzB,IAAI,CAAC,CAAC,EAAE,CAAC;IACT,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;QACT,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,EAAE,CAAC;IACX,CAAC;AACH,CAAC,CAAC;AAQF,QAAQ,CAAC,SAAS,CAAC,YAAY,GAAG;IAChC,IAAI,CAAC,CAAC;IACN,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAI9B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,IAAI,CAAC,CAAC,EAAE,CAAC;IACX,CAAC;AACH,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG;IACzB,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAC9B,IAAI,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC;IACrD,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;AACjC,CAAC,CAAC;AAMF,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG;IAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AAC3B,CAAC,CAAC;AAMF,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO;IACpC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvB,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACZ,CAAC;IACD,EAAE,CAAC,OAAO,CAAC,UAAU,OAAO;QAC1B,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO;IACrC,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,gBAAgB,EAAE,EAAE,KAAK;IACvB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC;IACT,CAAC;IACD,EAAE,CAAC,cAAc,EAAE,CAAC;IACpB,EAAE,CAAC,eAAe,EAAE,CAAC;IACrB,MAAM,CAAC,KAAK,CAAC;AACf,CAAC;AAED,kBAAkB,KAAK,EAAE,MAAM;IAC7B;QACE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IACD,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAC/B,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,iBAAiB,GAAG,EAAE,EAAE;IACtB,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,EAAE,CAAC;QACX,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;YAAC,MAAM,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,CAAC,CAAC,CAAC,CAAC;AACZ,CAAC;AAED,2BAA2B,IAAI,EAAE,EAAE;IACjC,IAAI,aAAa,GACb,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;QAC/D,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;IAEzE,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,aAAa,CAAC;IACvB,CAAC;IAGD,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;AAC3D,CAAC;AAGD,QAAQ,CAAC,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC;AAE3C,oBAAoB,EAAE,EAAE,EAAE,EAAE,EAAE;IAC5B,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IAEvC,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,KAAK,GAAG,QAAQ,EAClB,EAAE,GAAG,CAAC,CAAC,EACP,CAAC,GAAG,CAAC,EACL,CAAC,EACD,EAAE,EACF,EAAE,EACF,EAAE,EACF,IAAI,CAAC;IAEP,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACxB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACV,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACV,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEV,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAEnD,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;YACf,EAAE,GAAG,CAAC,CAAC;YACP,KAAK,CAAC;QACR,CAAC;QAED,EAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;YACjB,KAAK,GAAG,IAAI,CAAC;YACb,EAAE,GAAG,CAAC,CAAC;QACT,CAAC;IACH,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AACtC,CAAC;AAED,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC;AAGvB,UAAU,CAAC,QAAQ,GAAG,UAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IACnD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;UAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;UAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,cAAc,GAAG,EAAE,IAAI,EAAE,GAAG;IAC1B,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/C,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED,kCAAkC,EAAE;IAClC,MAAM,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE;QACtB,EAAE,CAAC,OAAO,KAAK,EAAE;QACjB,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,cAAc,GAAG;IACf,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;QAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC;IACnB,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;QAChB,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,MAAM,CAAC,IAAI,CAAC;AACd,CAAC;AAMD,QAAQ,CAAC,YAAY,GAAG,cAAxB,CAAA,YAAoC,CAAC;AACrC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAQ7B,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;AACjB,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;AACnB,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;AAEzB,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC"} \ No newline at end of file +{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(parentElement: HTMLElement) {\n super();\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n this.syncScrollArea();\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = false; // autowrap\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"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C,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC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"} \ No newline at end of file diff --git a/package.json b/package.json index 2eaaf2ab..3e8a8d55 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "2.3.0", + "version": "2.3.1", "ignore": [ "demo", "test", From f7bc0fba4dca0cbe8581db6af6da78391b337cb6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 18:57:45 -0800 Subject: [PATCH 106/211] Remove unnecessary variables --- src/Linkifier.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index adb96566..d97f4d14 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -18,13 +18,13 @@ const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; const bodyClause = hostClause + pathClause; const start = '(?:^|' + negatedDomainCharacterSet + ')('; const end = ')($|' + negatedPathCharacterSet + ')'; -const lenientUrlClause = start + protocolClause + '?' + bodyClause + end; -const strictUrlClause = start + protocolClause + bodyClause + end; -const lenientUrlRegex = new RegExp(lenientUrlClause); -const strictUrlRegex = new RegExp(strictUrlClause); +const strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); export type LinkHandler = (uri: string) => void; +/** + * The Linkifier applies links to rows shortly after they have been refreshed. + */ export class Linkifier { private _rows: HTMLElement[]; private _rowTimeoutIds: number[]; From 1306431e7c3883e80f29707eeb327693ccf5e306 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 19:53:32 -0800 Subject: [PATCH 107/211] Add PhantomJS test support and CharMeasure tests Fixes #534 --- gulpfile.js | 5 +++ package.json | 1 + src/Interfaces.ts | 6 +++ src/utils/CharMeasure.phantom.ts | 65 ++++++++++++++++++++++++++++++++ src/xterm.js | 3 ++ test-harness.html | 22 +++++++++++ 6 files changed, 102 insertions(+) create mode 100644 src/utils/CharMeasure.phantom.ts create mode 100644 test-harness.html diff --git a/gulpfile.js b/gulpfile.js index 144b8831..2aaf21ac 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,6 +3,7 @@ const buffer = require('vinyl-buffer'); const fs = require('fs-extra'); const gulp = require('gulp'); const merge = require('merge-stream'); +const mochaPhantom = require('gulp-mocha-phantomjs'); const sorcery = require('sorcery'); const source = require('vinyl-source-stream'); const sourcemaps = require('gulp-sourcemaps'); @@ -70,6 +71,10 @@ gulp.task('browserify', ['tsc'], function() { return merge(bundleStream, copyAddons, copyStylesheets); }); +gulp.task('test-phantom', function () { + return gulp.src('test-harness.html') + .pipe(mochaPhantom()); +}); /** * Use `sorcery` to resolve the source map chain and point back to the TypeScript files. diff --git a/package.json b/package.json index 3e8a8d55..8e766d2f 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "glob": "^7.0.5", "gulp": "^3.9.1", "gulp-cli": "^1.2.2", + "gulp-mocha-phantomjs": "^0.12.0", "gulp-sourcemaps": "1.9.1", "gulp-typescript": "^3.1.3", "jsdoc": "3.4.3", diff --git a/src/Interfaces.ts b/src/Interfaces.ts index c876d256..92094c95 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -44,6 +44,12 @@ export interface ITerminal { emit(event: string, data: any); } +export interface ICharMeasure { + width: number; + height: number; + measure(): void; +} + interface ICircularList { length: number; maxLength: number; diff --git a/src/utils/CharMeasure.phantom.ts b/src/utils/CharMeasure.phantom.ts new file mode 100644 index 00000000..f8173dc6 --- /dev/null +++ b/src/utils/CharMeasure.phantom.ts @@ -0,0 +1,65 @@ +/** + * @license MIT + */ +import { ICharMeasure, ITerminal } from '../Interfaces'; + +declare var assert: Chai.Assert; +declare var Terminal: ITerminal; + +// Do not describe tests unless in PhantomJS environment +if (typeof Terminal !== 'undefined') { + + const CharMeasure = (Terminal).CharMeasure; + + describe('CharMeasure', () => { + const parentElement = document.createElement('div'); + let charMeasure: ICharMeasure; + + beforeEach(() => { + charMeasure = new CharMeasure(parentElement); + document.querySelector('#xterm').appendChild(parentElement); + }); + + afterEach(() => { + if (parentElement && parentElement.parentElement) { + parentElement.parentElement.removeChild(parentElement); + } + }); + + describe('measure', () => { + it('should be performed async on first call', done => { + assert.equal(charMeasure.width, null); + charMeasure.measure(); + assert.equal(charMeasure.width, null); + setTimeout(() => { + assert.isTrue(charMeasure.width > 0); + done(); + }, 0); + }); + + it('should be performed sync on successive calls', done => { + charMeasure.measure(); + setTimeout(() => { + const firstWidth = charMeasure.width; + parentElement.style.fontSize = '2em'; + charMeasure.measure(); + assert.equal(charMeasure.width, firstWidth * 2); + done(); + }, 0); + }); + + it('should NOT do a measure when the parent is hidden', done => { + charMeasure.measure(); + setTimeout(() => { + const firstWidth = charMeasure.width; + parentElement.style.display = 'none'; + parentElement.style.fontSize = '2em'; + charMeasure.measure(); + assert.equal(charMeasure.width, firstWidth); + done(); + }, 0); + }); + }); + }); + +} diff --git a/src/xterm.js b/src/xterm.js index 314a76d0..f76c01b5 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2237,6 +2237,9 @@ function keys(obj) { Terminal.EventEmitter = EventEmitter; Terminal.inherits = inherits; +// Expose for Phantom.JS tests +Terminal.CharMeasure = CharMeasure; + /** * Adds an event listener to the terminal. * diff --git a/test-harness.html b/test-harness.html new file mode 100644 index 00000000..8c5f0b30 --- /dev/null +++ b/test-harness.html @@ -0,0 +1,22 @@ + + + + + + + +
+
+ + + + + + + + From e8adf8ad2b080ca6e9baff3a4371648cec74300e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 20:06:14 -0800 Subject: [PATCH 108/211] Use gulp-mocha and attach run both test type in npm test --- gulpfile.js | 14 ++++++++++---- package.json | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 2aaf21ac..f961b699 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,7 +3,8 @@ const buffer = require('vinyl-buffer'); const fs = require('fs-extra'); const gulp = require('gulp'); const merge = require('merge-stream'); -const mochaPhantom = require('gulp-mocha-phantomjs'); +const mocha = require('gulp-mocha'); +const mochaPhantomJs = require('gulp-mocha-phantomjs'); const sorcery = require('sorcery'); const source = require('vinyl-source-stream'); const sourcemaps = require('gulp-sourcemaps'); @@ -71,9 +72,14 @@ gulp.task('browserify', ['tsc'], function() { return merge(bundleStream, copyAddons, copyStylesheets); }); -gulp.task('test-phantom', function () { +gulp.task('test-mocha', function () { + return gulp.src(['lib/*test.js', 'lib/**/*test.js'], {read: false}) + .pipe(mocha()) +}); + +gulp.task('test-mocha-phantomjs', function () { return gulp.src('test-harness.html') - .pipe(mochaPhantom()); + .pipe(mochaPhantomJs()); }); /** @@ -88,5 +94,5 @@ gulp.task('sorcery', ['browserify'], function () { }); gulp.task('build', ['sorcery']); - +gulp.task('test', ['test-mocha', 'test-mocha-phantomjs']); gulp.task('default', ['build']); diff --git a/package.json b/package.json index 8e766d2f..c95de73b 100644 --- a/package.json +++ b/package.json @@ -47,12 +47,12 @@ "glob": "^7.0.5", "gulp": "^3.9.1", "gulp-cli": "^1.2.2", + "gulp-mocha": "^3.0.1", "gulp-mocha-phantomjs": "^0.12.0", "gulp-sourcemaps": "1.9.1", "gulp-typescript": "^3.1.3", "jsdoc": "3.4.3", "merge-stream": "^1.0.1", - "mocha": "2.5.3", "node-pty": "^0.4.1", "nodemon": "1.10.2", "sleep": "^3.0.1", @@ -68,7 +68,7 @@ "start": "node demo/app", "dev": "nodemon -e js,ts --watch src --watch demo --exec npm start", "lint": "tslint src/*.ts src/**/*.ts", - "test": "mocha --recursive ./lib", + "test": "gulp test", "build:docs": "jsdoc -c jsdoc.json", "build": "gulp build", "prepublish": "npm run build" From 8dc9ec5733a8a081438f90f93ba3a775bb4abad9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 20:20:18 -0800 Subject: [PATCH 109/211] Only show underline on hover --- src/xterm.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index 43f2594c..41dda53c 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -73,12 +73,12 @@ .terminal a { color: inherit; - /* Feature underline on links even if they have no href */ - text-decoration: underline; + text-decoration: none; } .terminal a:hover { cursor: pointer; + text-decoration: underline; } .terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { From 34582f9f65a0a1c778762d05bb5a4ddf97494982 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 20:21:18 -0800 Subject: [PATCH 110/211] Remove logs --- src/Linkifier.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index d97f4d14..07573421 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -74,24 +74,19 @@ export class Linkifier { return; } - console.log('found uri: ' + uri); const linkElement = this._createAnchorElement(uri); // TODO: Check if childNodes check is needed if (node.textContent.trim().length === uri.length) { // Matches entire string - console.log('match entire string'); if (node.nodeType === Node.TEXT_NODE) { - console.log('text node'); this._replaceNode(node, linkElement); } else { - console.log('element'); const element = (node); element.innerHTML = ''; element.appendChild(linkElement); } } else { // Matches part of string - console.log('part of string'); this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); } } @@ -167,19 +162,16 @@ export class Linkifier { if (substringIndex === 0) { // Replace with - console.log('Replace with '); const rightText = fullText.substring(substring.length); const rightTextNode = document.createTextNode(rightText); this._replaceNode(node, newNode, rightTextNode); } else if (substringIndex === targetNode.textContent.length - substring.length) { // Replace with - console.log('Replace with '); const leftText = fullText.substring(0, substringIndex); const leftTextNode = document.createTextNode(leftText); this._replaceNode(node, leftTextNode, newNode); } else { // Replace with - console.log('Replace with '); const leftText = fullText.substring(0, substringIndex); const leftTextNode = document.createTextNode(leftText); const rightText = fullText.substring(substringIndex + substring.length); From 7167b06bf85ac8dc02649944f2d9dda2225619bb Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 Feb 2017 20:44:22 -0800 Subject: [PATCH 111/211] Add custom link handlers, use generic way for http handler --- src/Linkifier.ts | 82 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 07573421..94a7f55d 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -22,17 +22,25 @@ const strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); export type LinkHandler = (uri: string) => void; +type LinkMatcher = {id: number, regex: RegExp, handler: LinkHandler}; + +const HYPERTEXT_LINK_MATCHER_ID = 0; + /** * The Linkifier applies links to rows shortly after they have been refreshed. */ export class Linkifier { + private static _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; + private _rows: HTMLElement[]; private _rowTimeoutIds: number[]; - private _hypertextLinkHandler: LinkHandler; + private _linkMatchers: LinkMatcher[]; constructor(rows: HTMLElement[]) { this._rows = rows; this._rowTimeoutIds = []; + this._linkMatchers = []; + this.registerLinkMatcher(strictUrlRegex, null); } /** @@ -47,9 +55,46 @@ export class Linkifier { this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), TIME_BEFORE_LINKIFY); } - // TODO: Support local links + /** + * Attaches a handler for hypertext links, overriding default behavior. + * @param {LinkHandler} handler The handler to use, this can be cleared with + * null. + */ public attachHypertextLinkHandler(handler: LinkHandler): void { - this._hypertextLinkHandler = handler; + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; + } + + /** + * Registers a link matcher, allowing custom link patterns to be matched and + * handled. + * @param {RegExp} regex The regular expression the search for. + * @param {LinkHandler} handler The callback when the link is called. + * @return {number} The ID of the new matcher, this can be used to deregister. + */ + public registerLinkMatcher(regex: RegExp, handler: LinkHandler): number { + if (Linkifier._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { + throw new Error('handler cannot be falsy'); + } + const matcher: LinkMatcher = { + id: Linkifier._nextLinkMatcherId++, + regex, + handler + }; + this._linkMatchers.push(matcher); + return matcher.id; + } + + /** + * Deregisters a link matcher if it has been registered. + * @param {number} matcherId The link matcher's ID (returned after register) + */ + public deregisterLinkMatcher(matcherId: number): void { + // ID 0 is the hypertext link matcher which cannot be deregistered + for (let i = 1; i < this._linkMatchers.length; i++) { + if (this._linkMatchers[i].id === matcherId) { + this._linkMatchers.splice(i, 1); + } + } } /** @@ -58,11 +103,24 @@ export class Linkifier { */ private _linkifyRow(rowIndex: number): void { const rowHtml = this._rows[rowIndex].innerHTML; - const uri = this._findLinkMatch(rowHtml); - if (!uri) { - return; + for (let i = 0; i < this._linkMatchers.length; i++) { + const matcher = this._linkMatchers[i]; + const uri = this._findLinkMatch(rowHtml, matcher.regex); + if (uri) { + this._doLinkifyRow(rowIndex, uri, matcher.handler); + // Only allow a single LinkMatcher to trigger on any given row. + return; + } } + } + /** + * Linkifies a row given a specific handler. + * @param {number} rowIndex The index of the row to linkify. + * @param {string} uri The uri that has been found. + * @param {handler} handler The handler to trigger when the link is triggered. + */ + private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkHandler): void { // Iterate over nodes as we want to consider text nodes const nodes = this._rows[rowIndex].childNodes; for (let i = 0; i < nodes.length; i++) { @@ -74,7 +132,7 @@ export class Linkifier { return; } - const linkElement = this._createAnchorElement(uri); + const linkElement = this._createAnchorElement(uri, handler); // TODO: Check if childNodes check is needed if (node.textContent.trim().length === uri.length) { // Matches entire string @@ -98,8 +156,8 @@ export class Linkifier { * @param {string} html The HTML to search. * @return {string} The matching URI or null if not found. */ - private _findLinkMatch(html: string): string { - const match = html.match(strictUrlRegex); + private _findLinkMatch(html: string, regex: RegExp): string { + const match = html.match(regex); if (!match || match.length === 0) { return null; } @@ -111,11 +169,11 @@ export class Linkifier { * @param {string} uri The uri of the link. * @return {HTMLAnchorElement} The link. */ - private _createAnchorElement(uri: string): HTMLAnchorElement { + private _createAnchorElement(uri: string, handler: LinkHandler): HTMLAnchorElement { const element = document.createElement('a'); element.textContent = uri; - if (this._hypertextLinkHandler) { - element.addEventListener('click', () => this._hypertextLinkHandler(uri)); + if (handler) { + element.addEventListener('click', () => handler(uri)); } else { element.href = uri; // Force link on another tab so work is not lost From 3bf31aa478ef8d7747f7c30face8f28382190594 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Feb 2017 20:09:47 -0800 Subject: [PATCH 112/211] Polish --- src/Linkifier.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 94a7f55d..e502289e 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -56,7 +56,8 @@ export class Linkifier { } /** - * Attaches a handler for hypertext links, overriding default behavior. + * Attaches a handler for hypertext links, overriding default behavior + * for standard http(s) links. * @param {LinkHandler} handler The handler to use, this can be cleared with * null. */ @@ -133,7 +134,6 @@ export class Linkifier { } const linkElement = this._createAnchorElement(uri, handler); - // TODO: Check if childNodes check is needed if (node.textContent.trim().length === uri.length) { // Matches entire string if (node.nodeType === Node.TEXT_NODE) { From 551159e0c33ea72b1070c53f3c2bd4b65652cd9c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Feb 2017 20:10:01 -0800 Subject: [PATCH 113/211] Remove linkify addon --- src/addons/linkify/index.html | 36 ------ src/addons/linkify/linkify.js | 207 -------------------------------- src/addons/linkify/package.json | 5 - 3 files changed, 248 deletions(-) delete mode 100644 src/addons/linkify/index.html delete mode 100644 src/addons/linkify/linkify.js delete mode 100644 src/addons/linkify/package.json diff --git a/src/addons/linkify/index.html b/src/addons/linkify/index.html deleted file mode 100644 index 5f429326..00000000 --- a/src/addons/linkify/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - -
- - - \ No newline at end of file diff --git a/src/addons/linkify/linkify.js b/src/addons/linkify/linkify.js deleted file mode 100644 index d2391026..00000000 --- a/src/addons/linkify/linkify.js +++ /dev/null @@ -1,207 +0,0 @@ -/** - * Methods for turning URL subscrings in the terminal's content into links (`a` DOM elements). - * @module xterm/addons/linkify/linkify - * @license MIT - */ - -(function (linkify) { - if (typeof exports === 'object' && typeof module === 'object') { - /* - * CommonJS environment - */ - module.exports = linkify(require('../../xterm')); - } else if (typeof define == 'function') { - /* - * Require.js is available - */ - define(['../../xterm'], linkify); - } else { - /* - * Plain browser environment - */ - linkify(window.Terminal); - } -})(function (Xterm) { - 'use strict'; - - var exports = {}, - protocolClause = '(https?:\\/\\/)', - domainCharacterSet = '[\\da-z\\.-]+', - negatedDomainCharacterSet = '[^\\da-z\\.-]+', - domainBodyClause = '(' + domainCharacterSet + ')', - tldClause = '([a-z\\.]{2,6})', - ipClause = '((\\d{1,3}\\.){3}\\d{1,3})', - portClause = '(:\\d{1,5})', - hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?', - pathClause = '(\\/[\\/\\w\\.-]*)*', - negatedPathCharacterSet = '[^\\/\\w\\.-]+', - bodyClause = hostClause + pathClause, - start = '(?:^|' + negatedDomainCharacterSet + ')(', - end = ')($|' + negatedPathCharacterSet + ')', - lenientUrlClause = start + protocolClause + '?' + bodyClause + end, - strictUrlClause = start + protocolClause + bodyClause + end, - lenientUrlRegex = new RegExp(lenientUrlClause), - strictUrlRegex = new RegExp(strictUrlClause); - - /** - * Converts all valid URLs found in the given terminal line into - * hyperlinks. The terminal line can be either the HTML element itself - * or the index of the termina line in the children of the terminal - * rows container. - * - * @param {Xterm} terminal - The terminal that owns the given line. - * @param {number|HTMLDivElement} line - The terminal line that should get - * "linkified". - * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is - * false, the regex requires a protocol clause. Defaults to true. - * @param {string} target - Sets target="" attribute with value provided to links. - * Default doesn't set target attribute - * @emits linkify - * @emits linkify:line - */ - exports.linkifyTerminalLine = function (terminal, line, lenient, target) { - if (typeof line == 'number') { - line = terminal.rowContainer.children[line]; - } else if (! (line instanceof HTMLDivElement)) { - var message = 'The "line" argument should be either a number'; - message += ' or an HTMLDivElement'; - - throw new TypeError(message); - } - - if (typeof target === 'undefined') { - target = ''; - } else { - target = 'target="' + target + '"'; - } - - var buffer = document.createElement('span'), - nodes = line.childNodes; - - for (var j=0; j' + url + '
', - newHTML = nodeHTML.replace(url, link); - - line.innerHTML = line.innerHTML.replace(nodeHTML, newHTML); - } - - /** - * This event gets emitted when conversion of all URL susbtrings - * to HTML anchor elements (links) has finished, for a specific - * line of the current Xterm instance. - * - * @event linkify:line - */ - terminal.emit('linkify:line', line); - }; - - /** - * Finds a link within a block of text. - * - * @param {string} text - The text to search . - * @param {boolean} lenient - Whether to use the lenient search. - * @return {string} A URL. - */ - exports.findLinkMatch = function (text, lenient) { - var match = text.match(lenient ? lenientUrlRegex : strictUrlRegex); - if (!match || match.length === 0) { - return null; - } - return match[1]; - } - - /** - * Converts all valid URLs found in the terminal view into hyperlinks. - * - * @param {Xterm} terminal - The terminal that should get "linkified". - * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is - * false, the regex requires a protocol clause. Defaults to true. - * @param {string} target - Sets target="" attribute with value provided to links. - * Default doesn't set target attribute - * @emits linkify - * @emits linkify:line - */ - exports.linkify = function (terminal, lenient, target) { - var rows = terminal.rowContainer.children; - - lenient = (typeof lenient == "boolean") ? lenient : true; - for (var i=0; i Date: Thu, 9 Feb 2017 20:12:35 -0800 Subject: [PATCH 114/211] Add license --- src/EscapeSequences.ts | 4 ++++ src/Linkifier.ts | 23 +++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/EscapeSequences.ts b/src/EscapeSequences.ts index 34dfde90..9542658f 100644 --- a/src/EscapeSequences.ts +++ b/src/EscapeSequences.ts @@ -1,3 +1,7 @@ +/** + * @license MIT + */ + /** * C0 control codes * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes diff --git a/src/Linkifier.ts b/src/Linkifier.ts index e502289e..693b1429 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -1,9 +1,10 @@ /** - * The time to wait after a row is changed before it is linkified. This prevents - * the costly operation of searching every row multiple times, pntentially a - * huge aount of times. + * @license MIT */ -const TIME_BEFORE_LINKIFY = 200; + +export type LinkHandler = (uri: string) => void; + +type LinkMatcher = {id: number, regex: RegExp, handler: LinkHandler}; const protocolClause = '(https?:\\/\\/)'; const domainCharacterSet = '[\\da-z\\.-]+'; @@ -20,12 +21,18 @@ const start = '(?:^|' + negatedDomainCharacterSet + ')('; const end = ')($|' + negatedPathCharacterSet + ')'; const strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); -export type LinkHandler = (uri: string) => void; - -type LinkMatcher = {id: number, regex: RegExp, handler: LinkHandler}; - +/** + * The ID of the built in http(s) link matcher. + */ const HYPERTEXT_LINK_MATCHER_ID = 0; +/** + * The time to wait after a row is changed before it is linkified. This prevents + * the costly operation of searching every row multiple times, pntentially a + * huge aount of times. + */ +const TIME_BEFORE_LINKIFY = 200; + /** * The Linkifier applies links to rows shortly after they have been refreshed. */ From a1d71c9198a79f7d644edf41b29af9836f543fee Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Feb 2017 20:35:06 -0800 Subject: [PATCH 115/211] Properly queue linkify after refresh --- src/xterm.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index f858af31..2a26aac0 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -548,6 +548,9 @@ Terminal.bindKeys = function(term) { on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper)); on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper)); term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper)); + term.on('refresh', function (data) { + term.queueLinkification(data.start, data.end) + }); }; @@ -1057,22 +1060,27 @@ Terminal.prototype.destroy = function() { /** * Tells the renderer to refresh terminal content between two rows (inclusive) at the next * opportunity. - * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) - * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) + * @param {number} start The row to start from (between 0 and this.rows - 1). + * @param {number} end The row to end at (between start and this.rows - 1). */ Terminal.prototype.refresh = function(start, end) { if (this.renderer) { this.renderer.queueRefresh(start, end); + } +}; - // TODO: DO this better - if (!this.linkifier) { - return; - } +/** + * Queues linkification for the specified rows. + * @param {number} start The row to start from (between 0 and this.rows - 1). + * @param {number} end The row to end at (between start and this.rows - 1). + */ +Terminal.prototype.queueLinkification = function(start, end) { + if (this.linkifier) { for (let i = start; i <= end; i++) { this.linkifier.linkifyRow(i); } } -}; +} /** * Display the cursor element @@ -1274,7 +1282,12 @@ Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) { this.customKeydownHandler = customKeydownHandler; } -// TODO: Doc +/** + * Attaches a http(s) link handler, forcing web links to behave differently to + * regular tags. This will trigger a refresh as links potentially need to be + * reconstructed. Calling this with null will remove the handler. + * @param {LinkHandler} handler The handler callback function. + */ Terminal.prototype.attachHypertextLinkHandler = function(handler) { if (!this.linkifier) { throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); From c8bb32165484d007bec1cbbd4c80234c93599405 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Feb 2017 21:08:50 -0800 Subject: [PATCH 116/211] Get custom link matcher working --- src/Linkifier.ts | 27 +++++++++++++++------------ src/xterm.js | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 693b1429..55b9f186 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -4,7 +4,7 @@ export type LinkHandler = (uri: string) => void; -type LinkMatcher = {id: number, regex: RegExp, handler: LinkHandler}; +type LinkMatcher = {id: number, regex: RegExp, matchIndex?: number, handler: LinkHandler}; const protocolClause = '(https?:\\/\\/)'; const domainCharacterSet = '[\\da-z\\.-]+'; @@ -47,7 +47,7 @@ export class Linkifier { this._rows = rows; this._rowTimeoutIds = []; this._linkMatchers = []; - this.registerLinkMatcher(strictUrlRegex, null); + this.registerLinkMatcher(strictUrlRegex, null, 1); } /** @@ -77,16 +77,19 @@ export class Linkifier { * handled. * @param {RegExp} regex The regular expression the search for. * @param {LinkHandler} handler The callback when the link is called. + * @param {number} matchIndex The index of the link from the regex.match(html) + * call. This defaults to 0 (for regular expressions without capture groups). * @return {number} The ID of the new matcher, this can be used to deregister. */ - public registerLinkMatcher(regex: RegExp, handler: LinkHandler): number { + public registerLinkMatcher(regex: RegExp, handler: LinkHandler, matchIndex?: number): number { if (Linkifier._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { throw new Error('handler cannot be falsy'); } const matcher: LinkMatcher = { id: Linkifier._nextLinkMatcherId++, regex, - handler + handler, + matchIndex }; this._linkMatchers.push(matcher); return matcher.id; @@ -113,7 +116,7 @@ export class Linkifier { const rowHtml = this._rows[rowIndex].innerHTML; for (let i = 0; i < this._linkMatchers.length; i++) { const matcher = this._linkMatchers[i]; - const uri = this._findLinkMatch(rowHtml, matcher.regex); + const uri = this._findLinkMatch(rowHtml, matcher.regex, matcher.matchIndex); if (uri) { this._doLinkifyRow(rowIndex, uri, matcher.handler); // Only allow a single LinkMatcher to trigger on any given row. @@ -135,11 +138,6 @@ export class Linkifier { const node = nodes[i]; const searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { - if (node.childNodes.length > 0) { - // This row has already been linkified - return; - } - const linkElement = this._createAnchorElement(uri, handler); if (node.textContent.trim().length === uri.length) { // Matches entire string @@ -147,6 +145,10 @@ export class Linkifier { this._replaceNode(node, linkElement); } else { const element = (node); + if (element.nodeName === 'A') { + // This row has already been linkified + return; + } element.innerHTML = ''; element.appendChild(linkElement); } @@ -161,14 +163,15 @@ export class Linkifier { /** * Finds a link match in a piece of HTML. * @param {string} html The HTML to search. + * @param {number} matchIndex The regex match index of the link. * @return {string} The matching URI or null if not found. */ - private _findLinkMatch(html: string, regex: RegExp): string { + private _findLinkMatch(html: string, regex: RegExp, matchIndex?: number): string { const match = html.match(regex); if (!match || match.length === 0) { return null; } - return match[1]; + return match[typeof matchIndex !== 'number' ? 0 : matchIndex]; } /** diff --git a/src/xterm.js b/src/xterm.js index 2a26aac0..c19b91a1 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1297,6 +1297,32 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { this.refresh(0, this.rows - 1); } + +/** + * Registers a link matcher, allowing custom link patterns to be matched and + * handled. + * @param {RegExp} regex The regular expression the search for. + * @param {LinkHandler} handler The callback when the link is called. + * @param {number} matchIndex The index of the link from the regex.match(html) + * call. This defaults to 0 (for regular expressions without capture groups). + * @return {number} The ID of the new matcher, this can be used to deregister. + */ +Terminal.prototype.registerLinkMatcher = function(regex, handler, matchIndex) { + if (this.linkifier) { + return this.linkifier.registerLinkMatcher(regex, handler, matchIndex); + } +} + +/** + * Deregisters a link matcher if it has been registered. + * @param {number} matcherId The link matcher's ID (returned after register) + */ +Terminal.prototype.deregisterLinkMatcher = function(matcherId) { + if (this.linkifier) { + this.linkifier.deregisterLinkMatcher(matcherId); + } +} + /** * Handle a keydown event * Key Resources: From 1c030f57ef12b7a50a68d75ba34c29183feac372 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Feb 2017 21:12:28 -0800 Subject: [PATCH 117/211] Force a refresh after register/deregister link matcher --- src/Linkifier.ts | 5 ++++- src/xterm.js | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 55b9f186..29b1a953 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -98,14 +98,17 @@ export class Linkifier { /** * Deregisters a link matcher if it has been registered. * @param {number} matcherId The link matcher's ID (returned after register) + * @return {boolean} Whether a link matcher was found and deregistered. */ - public deregisterLinkMatcher(matcherId: number): void { + public deregisterLinkMatcher(matcherId: number): boolean { // ID 0 is the hypertext link matcher which cannot be deregistered for (let i = 1; i < this._linkMatchers.length; i++) { if (this._linkMatchers[i].id === matcherId) { this._linkMatchers.splice(i, 1); + return true; } } + return false; } /** diff --git a/src/xterm.js b/src/xterm.js index c19b91a1..a353dc2e 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1309,7 +1309,9 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { */ Terminal.prototype.registerLinkMatcher = function(regex, handler, matchIndex) { if (this.linkifier) { - return this.linkifier.registerLinkMatcher(regex, handler, matchIndex); + var matcherId = this.linkifier.registerLinkMatcher(regex, handler, matchIndex); + this.refresh(0, this.rows - 1); + return matcherId; } } @@ -1319,7 +1321,9 @@ Terminal.prototype.registerLinkMatcher = function(regex, handler, matchIndex) { */ Terminal.prototype.deregisterLinkMatcher = function(matcherId) { if (this.linkifier) { - this.linkifier.deregisterLinkMatcher(matcherId); + if (this.linkifier.deregisterLinkMatcher(matcherId)) { + this.refresh(0, this.rows - 1); + } } } From 1ee774d01dfa9d1f781488c6a9560e16fc297f7c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Feb 2017 22:03:31 -0800 Subject: [PATCH 118/211] Remove linkify test --- src/Linkifier.ts | 16 ++++++----- src/test/addons/linkify-test.js | 48 --------------------------------- 2 files changed, 9 insertions(+), 55 deletions(-) delete mode 100644 src/test/addons/linkify-test.js diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 29b1a953..394d9ba7 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -75,7 +75,9 @@ export class Linkifier { /** * Registers a link matcher, allowing custom link patterns to be matched and * handled. - * @param {RegExp} regex The regular expression the search for. + * @param {RegExp} regex The regular expression the search for, specifically + * this searches the textContent of the rows. You will want to use \s to match + * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. * @param {number} matchIndex The index of the link from the regex.match(html) * call. This defaults to 0 (for regular expressions without capture groups). @@ -116,10 +118,10 @@ export class Linkifier { * @param {number} rowIndex The index of the row to linkify. */ private _linkifyRow(rowIndex: number): void { - const rowHtml = this._rows[rowIndex].innerHTML; + const text = this._rows[rowIndex].textContent; for (let i = 0; i < this._linkMatchers.length; i++) { const matcher = this._linkMatchers[i]; - const uri = this._findLinkMatch(rowHtml, matcher.regex, matcher.matchIndex); + const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { this._doLinkifyRow(rowIndex, uri, matcher.handler); // Only allow a single LinkMatcher to trigger on any given row. @@ -164,13 +166,13 @@ export class Linkifier { } /** - * Finds a link match in a piece of HTML. - * @param {string} html The HTML to search. + * Finds a link match in a piece of text. + * @param {string} text The text to search. * @param {number} matchIndex The regex match index of the link. * @return {string} The matching URI or null if not found. */ - private _findLinkMatch(html: string, regex: RegExp, matchIndex?: number): string { - const match = html.match(regex); + private _findLinkMatch(text: string, regex: RegExp, matchIndex?: number): string { + const match = text.match(regex); if (!match || match.length === 0) { return null; } diff --git a/src/test/addons/linkify-test.js b/src/test/addons/linkify-test.js deleted file mode 100644 index 285bfbb1..00000000 --- a/src/test/addons/linkify-test.js +++ /dev/null @@ -1,48 +0,0 @@ -var assert = require('chai').assert; -var Terminal = require('../../xterm'); -var linkify = require('../../addons/linkify/linkify'); - -describe('linkify addon', function () { - var xterm; - - describe('API', function () { - it('should define Terminal.prototype.linkify', function () { - assert.isDefined(Terminal.prototype.linkify); - }); - it('should define Terminal.prototype.linkifyTerminalLine', function () { - assert.isDefined(Terminal.prototype.linkifyTerminalLine); - }); - }); - - describe('findUrlMatchOnLine', function () { - describe('strict regex', function () { - it('should match when the entire text is a match', function () { - assert.equal(linkify.findLinkMatch('http://github.com', false), 'http://github.com'); - assert.equal(linkify.findLinkMatch('http://127.0.0.1', false), 'http://127.0.0.1'); - }); - it('should match simple domains', function () { - assert.equal(linkify.findLinkMatch('foo http://github.com bar', false), 'http://github.com'); - assert.equal(linkify.findLinkMatch('foo http://www.github.com bar', false), 'http://www.github.com'); - assert.equal(linkify.findLinkMatch('foo https://github.com bar', false), 'https://github.com'); - assert.equal(linkify.findLinkMatch('foo https://www.github.com bar', false), 'https://www.github.com'); - }); - it('should match web addresses with alpha paths', function () { - assert.equal(linkify.findLinkMatch('foo http://github.com/a/b/c bar', false), 'http://github.com/a/b/c'); - assert.equal(linkify.findLinkMatch('foo http://www.github.com/a/b/c bar', false), 'http://www.github.com/a/b/c'); - }); - it('should not include whitespace surrounding a match', function () { - assert.equal(linkify.findLinkMatch(' http://github.com', false), 'http://github.com'); - assert.equal(linkify.findLinkMatch('http://github.com ', false), 'http://github.com'); - assert.equal(linkify.findLinkMatch(' http://github.com ', false), 'http://github.com'); - }); - it('should match IP addresses', function () { - assert.equal(linkify.findLinkMatch('foo http://127.0.0.1 bar', false), 'http://127.0.0.1'); - assert.equal(linkify.findLinkMatch('foo https://127.0.0.1 bar', false), 'https://127.0.0.1'); - }); - it('should match ports on both domains and IP addresses', function () { - assert.equal(linkify.findLinkMatch('foo http://127.0.0.1:8080 bar', false), 'http://127.0.0.1:8080'); - assert.equal(linkify.findLinkMatch('foo http://www.github.com:8080 bar', false), 'http://www.github.com:8080'); - }); - }); - }); -}); From c53183d94b3533d3f502ed8d53f9e4fbe6541e83 Mon Sep 17 00:00:00 2001 From: Aleksandr Andrienko Date: Fri, 10 Feb 2017 16:50:16 +0200 Subject: [PATCH 119/211] Fix default 'wraparoundMode' value for 'Soft reset'() XTERM terminal. --- src/InputHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 10e72e9d..37f41f34 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1394,7 +1394,7 @@ export class InputHandler implements IInputHandler { this._terminal.cursorHidden = false; this._terminal.insertMode = false; this._terminal.originMode = false; - this._terminal.wraparoundMode = false; // autowrap + this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false this._terminal.applicationKeypad = false; // ? this._terminal.viewport.syncScrollArea(); this._terminal.applicationCursor = false; From ee1de0980f4923d3638b7355b3dc7ed32abf50ce Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 Feb 2017 09:55:35 -0800 Subject: [PATCH 120/211] Perform initial viewport sync after CharMeasure is ready Fixes #539 --- src/Viewport.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Viewport.ts b/src/Viewport.ts index aaafbc5f..dc7ff7c3 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -35,7 +35,8 @@ export class Viewport { this.terminal.on('resize', this.syncScrollArea.bind(this)); this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); - this.syncScrollArea(); + // Perform this async to ensure the CharMeasure is ready. + setTimeout(() => this.syncScrollArea(), 0); } /** From 5183332f6e7b3d460cb8135905713180e398ec21 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 Feb 2017 12:29:36 -0800 Subject: [PATCH 121/211] Next link matcher ID must be non-static --- src/Linkifier.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 394d9ba7..8bd300cc 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -37,11 +37,10 @@ const TIME_BEFORE_LINKIFY = 200; * The Linkifier applies links to rows shortly after they have been refreshed. */ export class Linkifier { - private static _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; - private _rows: HTMLElement[]; private _rowTimeoutIds: number[]; private _linkMatchers: LinkMatcher[]; + private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; constructor(rows: HTMLElement[]) { this._rows = rows; @@ -84,11 +83,11 @@ export class Linkifier { * @return {number} The ID of the new matcher, this can be used to deregister. */ public registerLinkMatcher(regex: RegExp, handler: LinkHandler, matchIndex?: number): number { - if (Linkifier._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { + if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { throw new Error('handler cannot be falsy'); } const matcher: LinkMatcher = { - id: Linkifier._nextLinkMatcherId++, + id: this._nextLinkMatcherId++, regex, handler, matchIndex From 92f27d3144df75654af39e7e90b640905eae0528 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 13 Feb 2017 09:48:22 -0800 Subject: [PATCH 122/211] Fix tests --- src/Viewport.test.ts | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/Viewport.test.ts b/src/Viewport.test.ts index 4fa77ec0..70ee97eb 100644 --- a/src/Viewport.test.ts +++ b/src/Viewport.test.ts @@ -41,13 +41,17 @@ describe('Viewport', () => { }); describe('refresh', () => { - it('should set the line-height of the terminal', () => { - assert.equal(viewportElement.style.lineHeight, CHARACTER_HEIGHT + 'px'); - assert.equal(terminal.rowContainer.style.lineHeight, CHARACTER_HEIGHT + 'px'); - charMeasure.height = 1; - viewport.refresh(); - assert.equal(viewportElement.style.lineHeight, '1px'); - assert.equal(terminal.rowContainer.style.lineHeight, '1px'); + it('should set the line-height of the terminal', done => { + // Allow CharMeasure to be initialized + setTimeout(() => { + assert.equal(viewportElement.style.lineHeight, CHARACTER_HEIGHT + 'px'); + assert.equal(terminal.rowContainer.style.lineHeight, CHARACTER_HEIGHT + 'px'); + charMeasure.height = 1; + viewport.refresh(); + assert.equal(viewportElement.style.lineHeight, '1px'); + assert.equal(terminal.rowContainer.style.lineHeight, '1px'); + done(); + }, 0); }); it('should set the height of the viewport when the line-height changed', () => { terminal.lines.push(''); @@ -62,17 +66,21 @@ describe('Viewport', () => { }); describe('syncScrollArea', () => { - it('should sync the scroll area', () => { - terminal.lines.push(''); - terminal.rows = 1; - assert.equal(scrollAreaElement.style.height, 0 * CHARACTER_HEIGHT + 'px'); - viewport.syncScrollArea(); - assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px'); - assert.equal(scrollAreaElement.style.height, 1 * CHARACTER_HEIGHT + 'px'); - terminal.lines.push(''); - viewport.syncScrollArea(); - assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px'); - assert.equal(scrollAreaElement.style.height, 2 * CHARACTER_HEIGHT + 'px'); + it('should sync the scroll area', done => { + // Allow CharMeasure to be initialized + setTimeout(() => { + terminal.lines.push(''); + terminal.rows = 1; + assert.equal(scrollAreaElement.style.height, 0 * CHARACTER_HEIGHT + 'px'); + viewport.syncScrollArea(); + assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px'); + assert.equal(scrollAreaElement.style.height, 1 * CHARACTER_HEIGHT + 'px'); + terminal.lines.push(''); + viewport.syncScrollArea(); + assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px'); + assert.equal(scrollAreaElement.style.height, 2 * CHARACTER_HEIGHT + 'px'); + done(); + }, 0); }); }); }); From 8fd44266a20fc6f9425a60e02e5b34bdb52d5354 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Mon, 13 Feb 2017 18:05:47 +0000 Subject: [PATCH 123/211] Bump version to 2.3.2 Signed-off-by: Paris Kasidiaris --- AUTHORS | 1 + bower.json | 2 +- dist/xterm.js | 35 +++++++++++++++++++++++++++++++---- dist/xterm.js.map | 2 +- package.json | 2 +- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index c3e3a97f..345e8d75 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,6 @@ List of xterm.js contributors. Updated before every release. +Aleksandr Andrienko Alessandro Nadalin Alexander Olsson Antonis Kalipetis diff --git a/bower.json b/bower.json index 95b72e97..ad780f43 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "xterm.js", - "version": "2.3.1", + "version": "2.3.2", "ignore": ["demo", "test", ".gitignore"], "main": [ "dist/xterm.js", diff --git a/dist/xterm.js b/dist/xterm.js index 93766079..d2e5dacd 100644 --- a/dist/xterm.js +++ b/dist/xterm.js @@ -158,6 +158,8 @@ exports.CHARSETS['='] = { '~': 'û' }; + + },{}],2:[function(require,module,exports){ "use strict"; var CompositionHelper = (function () { @@ -282,6 +284,8 @@ var CompositionHelper = (function () { }()); exports.CompositionHelper = CompositionHelper; + + },{}],3:[function(require,module,exports){ "use strict"; var C0; @@ -323,6 +327,8 @@ var C0; })(C0 = exports.C0 || (exports.C0 = {})); ; + + },{}],4:[function(require,module,exports){ "use strict"; ; @@ -378,6 +384,8 @@ var EventEmitter = (function () { }()); exports.EventEmitter = EventEmitter; + + },{}],5:[function(require,module,exports){ "use strict"; var EscapeSequences_1 = require("./EscapeSequences"); @@ -1302,6 +1310,8 @@ var wcwidth = (function (opts) { return wcwidth; })({ nul: 0, control: 0 }); + + },{"./Charsets":1,"./EscapeSequences":3}],6:[function(require,module,exports){ "use strict"; var EscapeSequences_1 = require("./EscapeSequences"); @@ -1775,6 +1785,8 @@ var Parser = (function () { }()); exports.Parser = Parser; + + },{"./Charsets":1,"./EscapeSequences":3}],7:[function(require,module,exports){ "use strict"; var MAX_REFRESH_FRAME_SKIP = 5; @@ -1984,10 +1996,13 @@ function checkBoldBroken(document) { return w1 !== w2; } + + },{}],8:[function(require,module,exports){ "use strict"; var Viewport = (function () { function Viewport(terminal, viewportElement, scrollArea, charMeasure) { + var _this = this; this.terminal = terminal; this.viewportElement = viewportElement; this.scrollArea = scrollArea; @@ -1998,7 +2013,7 @@ var Viewport = (function () { this.terminal.on('scroll', this.syncScrollArea.bind(this)); this.terminal.on('resize', this.syncScrollArea.bind(this)); this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); - this.syncScrollArea(); + setTimeout(function () { return _this.syncScrollArea(); }, 0); } Viewport.prototype.refresh = function () { if (this.charMeasure.height > 0) { @@ -2058,6 +2073,8 @@ var Viewport = (function () { }()); exports.Viewport = Viewport; + + },{}],9:[function(require,module,exports){ "use strict"; function prepareTextForClipboard(text) { @@ -2137,6 +2154,8 @@ function rightClickHandler(ev, term) { } exports.rightClickHandler = rightClickHandler; + + },{}],10:[function(require,module,exports){ "use strict"; var Generic_1 = require("./Generic"); @@ -2150,12 +2169,12 @@ exports.isIpad = platform === 'iPad'; exports.isIphone = platform === 'iPhone'; exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); + + },{"./Generic":13}],11:[function(require,module,exports){ "use strict"; var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) - if (b.hasOwnProperty(p)) - d[p] = b[p]; + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; @@ -2211,6 +2230,8 @@ var CharMeasure = (function (_super) { }(EventEmitter_js_1.EventEmitter)); exports.CharMeasure = CharMeasure; + + },{"../EventEmitter.js":4}],12:[function(require,module,exports){ "use strict"; var CircularList = (function () { @@ -2347,6 +2368,8 @@ var CircularList = (function () { }()); exports.CircularList = CircularList; + + },{}],13:[function(require,module,exports){ "use strict"; function contains(arr, el) { @@ -2355,6 +2378,8 @@ function contains(arr, el) { exports.contains = contains; ; + + },{}],14:[function(require,module,exports){ "use strict"; var CompositionHelper_1 = require("./CompositionHelper"); @@ -3865,6 +3890,8 @@ Terminal.off = off; Terminal.cancel = cancel; module.exports = Terminal; + + },{"./CompositionHelper":2,"./EscapeSequences":3,"./EventEmitter":4,"./InputHandler":5,"./Parser":6,"./Renderer":7,"./Viewport":8,"./handlers/Clipboard":9,"./utils/Browser":10,"./utils/CharMeasure":11,"./utils/CircularList":12}]},{},[14])(14) }); //# sourceMappingURL=xterm.js.map diff --git a/dist/xterm.js.map b/dist/xterm.js.map index 0c06e145..c20019cd 100644 --- a/dist/xterm.js.map +++ b/dist/xterm.js.map @@ -1 +1 @@ -{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(parentElement: HTMLElement) {\n super();\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n this.syncScrollArea();\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = false; // autowrap\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"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C,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC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"} \ No newline at end of file +{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(parentElement: HTMLElement) {\n super();\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n // Perform this async to ensure the CharMeasure is ready.\n setTimeout(() => this.syncScrollArea(), 0);\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = false; // autowrap\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"AcAA;;ADSa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AD3OA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AACA;AAAA;AApNa;;;;;;ADZb;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAAC;;;;;;ADlEA;AAED;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA9Da;;;;;;ADJb;AACA;AASA;AAEA;AAAA;AAAA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAkEA;AAEA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAj7Ca;AAm7Cb;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADriDA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAKA;AACA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAIA;AACA;AAGA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AAAA;AArda;;;;;;AD3Jb;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAC;AAED;AAEA;AAMA;AAAA;AAJA;AACA;AACA;AAKA;AACA;AACA;AAKA;AAQA;AACA;AACA;AACA;AACA;AACA;AAMA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAuBA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AAGA;AAAA;AACA;AAEA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAtQa;AA2Qb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADpSA;AAYA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AA/Ga;;;;;;ADcb;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAbA;AAmBA;AAGA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAbA;AAoBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAtBA;AAqCA;AACA;AAMA;AACA;AAGA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApDA;;;;;;AD/FA;AAEA;AACA;AACA;AAEa;AACA;AAKA;AACA;AACA;AACA;;;;;;;;;;;ADhBb;AAKA;AAAA;AAMA;AAAA;AAEA;;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAhDa;;;;;;ADJb;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAXA;AAaA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAWA;AAAA;AACA;AACA;;;AAAA;AAUA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AAhLa;;;;;;ADKb;AACA;AACA;AAFA;AAEC;;;;;;ADDD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAgBA;AAOA;AAMA;AAkBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAIA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAMA;AAKA;AAKA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AAQA;AAGA;AAGA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAKA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAIA;AAGA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAOA;AACA;AAQA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAYA;AACA;AAKA;AACA;AAIA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AACA;AAGA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAGA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AAGA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAQA;AACA;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAOA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AASA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAQA;AACA;AACA;AAEA;;;"} \ No newline at end of file diff --git a/package.json b/package.json index 380615c5..c6e6f429 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "2.3.1", + "version": "2.3.2", "ignore": [ "demo", "test", From aeb9f798c9017bc59a0248caa926c7f921213ea8 Mon Sep 17 00:00:00 2001 From: Lucian Buzzo Date: Mon, 13 Feb 2017 21:01:28 +0000 Subject: [PATCH 124/211] Make fit plugin guard against non-existent parent element. --- src/addons/fit/fit.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/addons/fit/fit.js b/src/addons/fit/fit.js index cacd9202..11fc6eb7 100644 --- a/src/addons/fit/fit.js +++ b/src/addons/fit/fit.js @@ -32,6 +32,9 @@ var exports = {}; exports.proposeGeometry = function (term) { + if (!term.element.parentElement) { + return null; + } var parentElementStyle = window.getComputedStyle(term.element.parentElement), parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), @@ -66,7 +69,9 @@ exports.fit = function (term) { var geometry = exports.proposeGeometry(term); - term.resize(geometry.cols, geometry.rows); + if (geometry) { + term.resize(geometry.cols, geometry.rows); + } }; Xterm.prototype.proposeGeometry = function () { From 345553012f73f2775b4e7f61d53c038ba80d9f22 Mon Sep 17 00:00:00 2001 From: Martin Wang Date: Tue, 14 Feb 2017 12:35:39 -0500 Subject: [PATCH 125/211] Let blink animation support style inheritance With this change, blinking cursor will use the same font and background color that set before. --- src/xterm.css | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index 27638e14..4bf18c5d 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -87,13 +87,10 @@ } @keyframes xterm-cursor-blink { - 0% { - background-color: #fff; - color: #000; - } + 0% { } 50% { background-color: transparent; - color: #FFF; + color: inherit; } } From 3b62aa444bb1ddac26981936c358b2dc7c33d9a7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 14 Feb 2017 19:45:08 -0800 Subject: [PATCH 126/211] Improve jsdoc --- src/Linkifier.ts | 2 +- src/xterm.js | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 8bd300cc..9da532dd 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -74,7 +74,7 @@ export class Linkifier { /** * Registers a link matcher, allowing custom link patterns to be matched and * handled. - * @param {RegExp} regex The regular expression the search for, specifically + * @param {RegExp} regex The regular expression to search for, specifically * this searches the textContent of the rows. You will want to use \s to match * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. diff --git a/src/xterm.js b/src/xterm.js index a353dc2e..358040a0 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1299,13 +1299,15 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { /** - * Registers a link matcher, allowing custom link patterns to be matched and - * handled. - * @param {RegExp} regex The regular expression the search for. - * @param {LinkHandler} handler The callback when the link is called. - * @param {number} matchIndex The index of the link from the regex.match(html) - * call. This defaults to 0 (for regular expressions without capture groups). - * @return {number} The ID of the new matcher, this can be used to deregister. + * Registers a link matcher, allowing custom link patterns to be matched and + * handled. + * @param {RegExp} regex The regular expression to search for, specifically + * this searches the textContent of the rows. You will want to use \s to match + * a space ' ' character for example. + * @param {LinkHandler} handler The callback when the link is called. + * @param {number} matchIndex The index of the link from the regex.match(html) + * call. This defaults to 0 (for regular expressions without capture groups). + * @return {number} The ID of the new matcher, this can be used to deregister. */ Terminal.prototype.registerLinkMatcher = function(regex, handler, matchIndex) { if (this.linkifier) { From c3f31b5f6535130e0d5dc1e63a395dbf775d6a99 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 14 Feb 2017 20:04:51 -0800 Subject: [PATCH 127/211] Apply link matchers in reverse This enables consumers to have full control. --- src/Linkifier.ts | 4 ++-- src/xterm.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 9da532dd..a2a5a5da 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -78,7 +78,7 @@ export class Linkifier { * this searches the textContent of the rows. You will want to use \s to match * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. - * @param {number} matchIndex The index of the link from the regex.match(html) + * @param {number} matchIndex The index of the link from the regex.match(text) * call. This defaults to 0 (for regular expressions without capture groups). * @return {number} The ID of the new matcher, this can be used to deregister. */ @@ -118,7 +118,7 @@ export class Linkifier { */ private _linkifyRow(rowIndex: number): void { const text = this._rows[rowIndex].textContent; - for (let i = 0; i < this._linkMatchers.length; i++) { + for (let i = this._linkMatchers.length - 1; i >= 0; i--) { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { diff --git a/src/xterm.js b/src/xterm.js index 358040a0..a6e756b2 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1305,7 +1305,7 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { * this searches the textContent of the rows. You will want to use \s to match * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. - * @param {number} matchIndex The index of the link from the regex.match(html) + * @param {number} matchIndex The index of the link from the regex.match(text) * call. This defaults to 0 (for regular expressions without capture groups). * @return {number} The ID of the new matcher, this can be used to deregister. */ From c4f431849bc0665f32efa005c5f2ef938c920a48 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 16 Feb 2017 22:41:08 -0800 Subject: [PATCH 128/211] Add a null check on linkifyRow --- src/Linkifier.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index a2a5a5da..b5b3247c 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -117,7 +117,11 @@ export class Linkifier { * @param {number} rowIndex The index of the row to linkify. */ private _linkifyRow(rowIndex: number): void { - const text = this._rows[rowIndex].textContent; + const row = this._rows[rowIndex]; + if (!row) { + return; + } + const text = row.textContent; for (let i = this._linkMatchers.length - 1; i >= 0; i--) { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); From 3f69da2455452ba5285d476c3b6e92d231789b64 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 17 Feb 2017 10:06:35 -0800 Subject: [PATCH 129/211] Support query string in linkifier --- src/Linkifier.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index b5b3247c..74c03adc 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -15,8 +15,9 @@ const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?'; const pathClause = '(\\/[\\/\\w\\.-]*)*'; +const queryStringClause = '(\\?[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;]*)?'; const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; -const bodyClause = hostClause + pathClause; +const bodyClause = hostClause + pathClause + queryStringClause; const start = '(?:^|' + negatedDomainCharacterSet + ')('; const end = ')($|' + negatedPathCharacterSet + ')'; const strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); From a10ee8f58c5d97f7e520872a2c5ebc5c03abc295 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 17 Feb 2017 10:18:37 -0800 Subject: [PATCH 130/211] Revert priority change, http handler needs to be top --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 74c03adc..6bc1d86f 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -123,7 +123,7 @@ export class Linkifier { return; } const text = row.textContent; - for (let i = this._linkMatchers.length - 1; i >= 0; i--) { + for (let i = 0; i < this._linkMatchers.length; i--) { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { From e6fc80c13b2e0769614f20ec8c3812f158df5951 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 17 Feb 2017 10:22:25 -0800 Subject: [PATCH 131/211] Fix link matcher iteration direction --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 6bc1d86f..04871e80 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -123,7 +123,7 @@ export class Linkifier { return; } const text = row.textContent; - for (let i = 0; i < this._linkMatchers.length; i--) { + for (let i = 0; i < this._linkMatchers.length; i++) { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { From 5452986ce32db941d5ee7fe44e3bbe8a91d2261c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 19 Feb 2017 12:34:36 -0800 Subject: [PATCH 132/211] Use CharMeasure to determine mouse coordinates Fixes #555 --- src/xterm.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index f76c01b5..8aa6236b 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -957,10 +957,8 @@ Terminal.prototype.bindMouse = function() { } // convert to cols/rows - w = self.element.clientWidth; - h = self.element.clientHeight; - x = Math.ceil((x / w) * self.cols); - y = Math.ceil((y / h) * self.rows); + x = Math.ceil(x / self.charMeasure.width); + y = Math.ceil(y / self.charMeasure.height); // be sure to avoid sending // bad positions to the program From d06c920a2d1276890a728103bf714be4f1881e12 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 19 Feb 2017 13:20:36 -0800 Subject: [PATCH 133/211] Hide CharMeasure element from assistive technologies --- src/utils/CharMeasure.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/CharMeasure.ts b/src/utils/CharMeasure.ts index 3344fed2..fdad40a9 100644 --- a/src/utils/CharMeasure.ts +++ b/src/utils/CharMeasure.ts @@ -34,6 +34,7 @@ export class CharMeasure extends EventEmitter { this._measureElement.style.top = '0'; this._measureElement.style.left = '-9999em'; this._measureElement.textContent = 'W'; + this._measureElement.setAttribute('aria-hidden', 'true'); this._parentElement.appendChild(this._measureElement); // Perform _doMeasure async if the element was just attached as sometimes // getBoundingClientRect does not return accurate values without this. From 99a270216c17cfc00eebafbf02c6a2215d49e9d5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 19 Feb 2017 15:17:03 -0800 Subject: [PATCH 134/211] Remove bad trim optimization from Linkifier This prevents whitespace from going missing after links are applied. Fixes #558 --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 04871e80..e0f5eb92 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -148,7 +148,7 @@ export class Linkifier { const searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { const linkElement = this._createAnchorElement(uri, handler); - if (node.textContent.trim().length === uri.length) { + if (node.textContent.length === uri.length) { // Matches entire string if (node.nodeType === Node.TEXT_NODE) { this._replaceNode(node, linkElement); From 695a9523fee3f7864f36d5fa89c2fe9be2ef49e6 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 22 Feb 2017 16:17:22 +0200 Subject: [PATCH 135/211] Fix #531: Submit code coverage to coveralls.io --- .gitignore | 3 +++ .travis.yml | 1 + gulpfile.js | 21 ++++++++++++++++++++- package.json | 5 ++++- src/test/test.js | 1 + 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index f44dfda2..d5531c1d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ npm-debug.log .env build/ .vscode/ + +# Directories needed for code coverage +/coverage/ diff --git a/.travis.yml b/.travis.yml index b32fc7ea..b98cb202 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,3 +16,4 @@ addons: notifications: email: false script: npm run $NPM_COMMAND +after_success: npm run coveralls diff --git a/gulpfile.js b/gulpfile.js index 8aa86b11..0043d7b1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,7 +1,9 @@ const browserify = require('browserify'); const buffer = require('vinyl-buffer'); +const coveralls = require('gulp-coveralls'); const fs = require('fs-extra'); const gulp = require('gulp'); +const istanbul = require('gulp-istanbul'); const merge = require('merge-stream'); const mocha = require('gulp-mocha'); const mochaPhantomJs = require('gulp-mocha-phantomjs'); @@ -70,9 +72,18 @@ gulp.task('browserify', ['tsc'], function() { return merge(bundleStream, copyAddons, copyStylesheets); }); -gulp.task('test-mocha', function () { +gulp.task('instrument-test', function () { + return gulp.src(['lib/**/*.js']) + // Covering files + .pipe(istanbul()) + // Force `require` to return covered files + .pipe(istanbul.hookRequire()); +}); + +gulp.task('test-mocha', ['instrument-test'], function () { return gulp.src(['lib/*test.js', 'lib/**/*test.js'], {read: false}) .pipe(mocha()) + .pipe(istanbul.writeReports()); }); gulp.task('test-mocha-phantomjs', function () { @@ -91,6 +102,14 @@ gulp.task('sorcery', ['browserify'], function () { chain.writeSync(); }); +/** + * Submit coverage results to coveralls.io + */ +gulp.task('coveralls', function () { + gulp.src('coverage/**/lcov.info') + .pipe(coveralls()); +}); + gulp.task('build', ['sorcery']); gulp.task('test', ['test-mocha', 'test-mocha-phantomjs']); gulp.task('default', ['build']); diff --git a/package.json b/package.json index 06a7492b..3019103f 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,8 @@ "glob": "^7.0.5", "gulp": "^3.9.1", "gulp-cli": "^1.2.2", + "gulp-coveralls": "^0.1.4", + "gulp-istanbul": "^1.1.1", "gulp-mocha": "^3.0.1", "gulp-mocha-phantomjs": "^0.12.0", "gulp-sourcemaps": "1.9.1", @@ -70,6 +72,7 @@ "test": "gulp test", "build:docs": "jsdoc -c jsdoc.json", "build": "gulp build", - "prepublish": "npm run build" + "prepublish": "npm run build", + "coveralls": "gulp coveralls" } } diff --git a/src/test/test.js b/src/test/test.js index d0d70686..716b48c4 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -550,6 +550,7 @@ describe('xterm.js', function() { describe('unicode - surrogates', function() { it('2 characters per cell', function () { + this.timeout(10000); // This is needed because istanbul patches code and slows it down var high = String.fromCharCode(0xD800); for (var i=0xDC00; i<=0xDCFF; ++i) { xterm.write(high + String.fromCharCode(i)); From e569b5669a2551bcc6717fc340fe0e18b4c39a85 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 22 Feb 2017 16:22:50 +0200 Subject: [PATCH 136/211] Add coveralls badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe75e6bc..7c82e74d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # xterm.js -[![xterm.js build status](https://api.travis-ci.org/sourcelair/xterm.js.svg)](https://travis-ci.org/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![xterm.js build status](https://api.travis-ci.org/sourcelair/xterm.js.svg)](https://travis-ci.org/sourcelair/xterm.js) [![Coverage Status](https://coveralls.io/repos/github/sourcelair/xterm.js/badge.svg)](https://coveralls.io/github/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Xterm.js is a terminal front-end component written in JavaScript that works in the browser. From 28d4ec779daeca1696fb8e512f65f51f5bec76f3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 23 Feb 2017 09:37:35 -0800 Subject: [PATCH 137/211] Fix localhost links --- src/Linkifier.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index e0f5eb92..7a813733 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -12,8 +12,9 @@ const negatedDomainCharacterSet = '[^\\da-z\\.-]+'; const domainBodyClause = '(' + domainCharacterSet + ')'; const tldClause = '([a-z\\.]{2,6})'; const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; +const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; -const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?'; +const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; const pathClause = '(\\/[\\/\\w\\.-]*)*'; const queryStringClause = '(\\?[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;]*)?'; const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; From b81068716366d061a693931c7c8a530c80735898 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 23 Feb 2017 09:42:59 -0800 Subject: [PATCH 138/211] Support linking = in query strings --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 7a813733..1381bf8b 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -16,7 +16,7 @@ const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; const pathClause = '(\\/[\\/\\w\\.-]*)*'; -const queryStringClause = '(\\?[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;]*)?'; +const queryStringClause = '(\\?[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;\\=]*)?'; const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; const bodyClause = hostClause + pathClause + queryStringClause; const start = '(?:^|' + negatedDomainCharacterSet + ')('; From 9aae43961f38e0a6f68e448f71d4917f1d1f5416 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 23 Feb 2017 09:53:20 -0800 Subject: [PATCH 139/211] Support linking hash fragments --- src/Linkifier.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 1381bf8b..4ec9018c 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -16,9 +16,11 @@ const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; const pathClause = '(\\/[\\/\\w\\.-]*)*'; -const queryStringClause = '(\\?[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;\\=]*)?'; +const queryStringHashFragmentCharacterSet = '[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;\\=]*'; +const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; +const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; -const bodyClause = hostClause + pathClause + queryStringClause; +const bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause; const start = '(?:^|' + negatedDomainCharacterSet + ')('; const end = ')($|' + negatedPathCharacterSet + ')'; const strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); From cb80ce0d2c5edc473c7ca3c401d0c42c8f50c365 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 23 Feb 2017 09:55:05 -0800 Subject: [PATCH 140/211] Link . and - in hash fragments and query strings --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 4ec9018c..6ead8e09 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -16,7 +16,7 @@ const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; const pathClause = '(\\/[\\/\\w\\.-]*)*'; -const queryStringHashFragmentCharacterSet = '[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;\\=]*'; +const queryStringHashFragmentCharacterSet = '[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;\\=\\.\\-]*'; const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; From ccadf3fccac5260eca83578387a282195e146383 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 23 Feb 2017 10:02:18 -0800 Subject: [PATCH 141/211] Support percent and numbers in query/hash fragments --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 6ead8e09..280ad42d 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -16,7 +16,7 @@ const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; const pathClause = '(\\/[\\/\\w\\.-]*)*'; -const queryStringHashFragmentCharacterSet = '[\\w\\[\\]\\(\\)\\/\\?\\!#@$&\'*+,:;\\=\\.\\-]*'; +const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;\\=\\.\\-]*'; const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; From 7279ee0f5ff3cb19116c8b897165a94ffacfb580 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 24 Feb 2017 08:56:11 -0800 Subject: [PATCH 142/211] Support % in URLs --- src/Linkifier.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 280ad42d..e8d6371d 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -15,11 +15,11 @@ const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; -const pathClause = '(\\/[\\/\\w\\.-]*)*'; +const pathClause = '(\\/[\\/\\w\\.\\-%]*)*'; const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;\\=\\.\\-]*'; const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; -const negatedPathCharacterSet = '[^\\/\\w\\.-]+'; +const negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; const bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause; const start = '(?:^|' + negatedDomainCharacterSet + ')('; const end = ')($|' + negatedPathCharacterSet + ')'; From 514eba0e4ec9b98268dfb3d921fb0545fb8528f7 Mon Sep 17 00:00:00 2001 From: Brian Mock Date: Sat, 25 Feb 2017 09:07:51 -0800 Subject: [PATCH 143/211] Fixes #562 adds Windows demo setup help --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7c82e74d..12ec9ef2 100644 --- a/README.md +++ b/README.md @@ -48,14 +48,29 @@ Xterm.js works seamlessly in Electron apps and may even work on earlier versions ## Demo -To launch the demo simply run: +### Linux or macOS + +Run the following commands: ``` -npm install -npm start +$ npm install +$ npm start ``` -Then open http://0.0.0.0:3000 in a web browser (use http://127.0.0.1:3000 if running under Windows). +Then open http://0.0.0.0:3000 in a web browser. + +### Windows + +First, ensure [node-gyp](https://github.com/nodejs/node-gyp) is installed and configured correctly, then run these commands. + +Note: Do not use ConEmu, as it seems to break the demo for some reason. + +``` +> npm install +> npm start +``` + +Then open http://127.0.0.1:3000 in a web browser. ## Getting Started @@ -77,7 +92,7 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t ``` -Finally instantiate the `Terminal` object and then call the `open` function with the DOM object of the `div`. +Finally instantiate the `Terminal` object and then call the `open` function with the DOM object of the `div`. ## Addons From 6198556e50cb8c22e91ecbd82becc0a05d2016b0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 27 Feb 2017 08:35:56 -0800 Subject: [PATCH 144/211] Implement link validation Fixes #570 --- src/Interfaces.ts | 22 ++++++++++++++++++++++ src/Linkifier.ts | 43 +++++++++++++++++++++++++++++++++++-------- src/Types.ts | 5 +++++ src/xterm.css | 5 +++++ src/xterm.js | 7 +++---- 5 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 src/Types.ts diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 92094c95..324eec16 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -2,6 +2,8 @@ * @license MIT */ +import { LinkMatcherValidationCallback } from './Types'; + export interface IBrowser { isNode: boolean; userAgent: string; @@ -64,6 +66,26 @@ interface ICircularList { shiftElements(start: number, count: number, offset: number): void; } +export interface LinkMatcherOptions { + /** + * The index of the link from the regex.match(text) call. This defaults to 0 + * (for regular expressions without capture groups). + */ + matchIndex?: number; + /** + * A callback that validates an individual link, returning true if valid and + * false if invalid. + */ + validationCallback?: LinkMatcherValidationCallback; +} + +/** + * + * @param a + */ +function a(a) { +} + /** * Handles actions generated by the parser. */ diff --git a/src/Linkifier.ts b/src/Linkifier.ts index e0f5eb92..73ad04a5 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -2,9 +2,20 @@ * @license MIT */ +import { LinkMatcherOptions } from './Interfaces'; +import { LinkMatcherValidationCallback } from './Types'; + export type LinkHandler = (uri: string) => void; -type LinkMatcher = {id: number, regex: RegExp, matchIndex?: number, handler: LinkHandler}; +type LinkMatcher = { + id: number, + regex: RegExp, + handler: LinkHandler, + matchIndex?: number, + validationCallback?: LinkMatcherValidationCallback; +}; + +const INVALID_LINK_CLASS = 'xterm-invalid-link'; const protocolClause = '(https?:\\/\\/)'; const domainCharacterSet = '[\\da-z\\.-]+'; @@ -79,11 +90,10 @@ export class Linkifier { * this searches the textContent of the rows. You will want to use \s to match * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. - * @param {number} matchIndex The index of the link from the regex.match(text) - * call. This defaults to 0 (for regular expressions without capture groups). + * @param {LinkMatcherOptions} [options] Options for the link matcher. * @return {number} The ID of the new matcher, this can be used to deregister. */ - public registerLinkMatcher(regex: RegExp, handler: LinkHandler, matchIndex?: number): number { + public registerLinkMatcher(regex: RegExp, handler: LinkHandler, options: LinkMatcherOptions = {}): number { if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { throw new Error('handler cannot be falsy'); } @@ -91,7 +101,8 @@ export class Linkifier { id: this._nextLinkMatcherId++, regex, handler, - matchIndex + matchIndex: options.matchIndex, + validationCallback: options.validationCallback }; this._linkMatchers.push(matcher); return matcher.id; @@ -123,11 +134,20 @@ export class Linkifier { return; } const text = row.textContent; + // TODO: Onl execute handler if isValid for (let i = 0; i < this._linkMatchers.length; i++) { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { - this._doLinkifyRow(rowIndex, uri, matcher.handler); + const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler); + // Fire validation callback + if (matcher.validationCallback) { + matcher.validationCallback(uri, isValid => { + if (!isValid) { + linkElement.classList.add(INVALID_LINK_CLASS); + } + }); + } // Only allow a single LinkMatcher to trigger on any given row. return; } @@ -139,8 +159,9 @@ export class Linkifier { * @param {number} rowIndex The index of the row to linkify. * @param {string} uri The uri that has been found. * @param {handler} handler The handler to trigger when the link is triggered. + * @return The link element if it was added, otherwise undefined. */ - private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkHandler): void { + private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkHandler): HTMLElement { // Iterate over nodes as we want to consider text nodes const nodes = this._rows[rowIndex].childNodes; for (let i = 0; i < nodes.length; i++) { @@ -165,6 +186,7 @@ export class Linkifier { // Matches part of string this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); } + return linkElement; } } } @@ -192,7 +214,12 @@ export class Linkifier { const element = document.createElement('a'); element.textContent = uri; if (handler) { - element.addEventListener('click', () => handler(uri)); + element.addEventListener('click', () => { + // Only execute the handler if the link is not flagged as invalid + if (!element.classList.contains(INVALID_LINK_CLASS)) { + handler(uri); + } + }); } else { element.href = uri; // Force link on another tab so work is not lost diff --git a/src/Types.ts b/src/Types.ts new file mode 100644 index 00000000..1eafa101 --- /dev/null +++ b/src/Types.ts @@ -0,0 +1,5 @@ +/** + * @license MIT + */ + +export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; diff --git a/src/xterm.css b/src/xterm.css index f99eb688..0401e607 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -81,6 +81,11 @@ text-decoration: underline; } +.terminal a.xterm-invalid-link:hover { + cursor: default; + text-decoration: none; +} + .terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { background-color: #fff; color: #000; diff --git a/src/xterm.js b/src/xterm.js index d09d5fb2..69eb0a1f 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1303,13 +1303,12 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { * this searches the textContent of the rows. You will want to use \s to match * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. - * @param {number} matchIndex The index of the link from the regex.match(text) - * call. This defaults to 0 (for regular expressions without capture groups). + * @param {LinkMatcherOptions} [options] Options for the link matcher. * @return {number} The ID of the new matcher, this can be used to deregister. */ -Terminal.prototype.registerLinkMatcher = function(regex, handler, matchIndex) { +Terminal.prototype.registerLinkMatcher = function(regex, handler, options) { if (this.linkifier) { - var matcherId = this.linkifier.registerLinkMatcher(regex, handler, matchIndex); + var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options); this.refresh(0, this.rows - 1); return matcherId; } From 4c99c032cac4a01841466aa010b92786ebd30b10 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 27 Feb 2017 09:47:36 -0800 Subject: [PATCH 145/211] Add tests --- src/Interfaces.ts | 10 +++++- src/Linkifier.phantom.ts | 76 ++++++++++++++++++++++++++++++++++++++++ src/Linkifier.ts | 23 +++++++----- src/Types.ts | 1 + src/xterm.js | 1 + test-harness.html | 1 + 6 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 src/Linkifier.phantom.ts diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 324eec16..ca9de632 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -2,7 +2,8 @@ * @license MIT */ -import { LinkMatcherValidationCallback } from './Types'; +import { LinkMatcherOptions } from './Interfaces'; +import { LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; export interface IBrowser { isNode: boolean; @@ -52,6 +53,13 @@ export interface ICharMeasure { measure(): void; } +export interface ILinkifier { + linkifyRow(rowIndex: number): void; + attachHypertextLinkHandler(handler: LinkMatcherHandler): void; + registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: LinkMatcherOptions): number; + deregisterLinkMatcher(matcherId: number): boolean; +} + interface ICircularList { length: number; maxLength: number; diff --git a/src/Linkifier.phantom.ts b/src/Linkifier.phantom.ts new file mode 100644 index 00000000..01de4efc --- /dev/null +++ b/src/Linkifier.phantom.ts @@ -0,0 +1,76 @@ +/** + * @license MIT + */ +import { ITerminal, ILinkifier } from './Interfaces'; + +declare var assert: Chai.Assert; +declare var Terminal: ITerminal; + +// Do not describe tests unless in PhantomJS environment +if (typeof Terminal !== 'undefined') { + + const Linkifier = (Terminal).Linkifier; + Linkifier.setTimeBeforeLinkifyForTest(0); + + describe('Linkifier', () => { + let container: HTMLElement; + let rows: HTMLElement[]; + let linkifier: ILinkifier; + + beforeEach(() => { + container = document.createElement('div'); + document.querySelector('#xterm').appendChild(container); + rows = []; + linkifier = new Linkifier(rows); + }); + + afterEach(() => { + while (rows.length) { + container.removeChild(rows.pop()); + } + document.querySelector('#xterm').removeChild(container); + }); + + function addRow(text: string) { + const element = document.createElement('div'); + element.textContent = text; + container.appendChild(element); + rows.push(element); + } + + function clickElement(element: Node) { + const event = document.createEvent('MouseEvent'); + event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + element.dispatchEvent(event); + } + + describe('validationCallback', () => { + it('should enable link if true', done => { + addRow('test'); + linkifier.registerLinkMatcher(/test/, () => done(), { + validationCallback: (url, cb) => { + cb(true); + assert.equal((rows[0].firstChild).tagName, 'A'); + setTimeout(() => clickElement(rows[0].firstChild), 0); + } + }); + linkifier.linkifyRow(0); + }); + + it('should disable link if false', done => { + addRow('test'); + linkifier.registerLinkMatcher(/test/, () => assert.fail(), { + validationCallback: (url, cb) => { + cb(false); + assert.equal((rows[0].firstChild).tagName, 'A'); + setTimeout(() => clickElement(rows[0].firstChild), 0); + } + }); + linkifier.linkifyRow(0); + // Allow time for the click to be performed + setTimeout(() => done(), 10); + }); + }); + }); + +} diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 73ad04a5..9f29ba58 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -3,14 +3,12 @@ */ import { LinkMatcherOptions } from './Interfaces'; -import { LinkMatcherValidationCallback } from './Types'; - -export type LinkHandler = (uri: string) => void; +import { LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; type LinkMatcher = { id: number, regex: RegExp, - handler: LinkHandler, + handler: LinkMatcherHandler, matchIndex?: number, validationCallback?: LinkMatcherValidationCallback; }; @@ -43,7 +41,7 @@ const HYPERTEXT_LINK_MATCHER_ID = 0; * the costly operation of searching every row multiple times, pntentially a * huge aount of times. */ -const TIME_BEFORE_LINKIFY = 200; +let TIME_BEFORE_LINKIFY = 200; /** * The Linkifier applies links to rows shortly after they have been refreshed. @@ -79,7 +77,7 @@ export class Linkifier { * @param {LinkHandler} handler The handler to use, this can be cleared with * null. */ - public attachHypertextLinkHandler(handler: LinkHandler): void { + public attachHypertextLinkHandler(handler: LinkMatcherHandler): void { this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; } @@ -93,7 +91,7 @@ export class Linkifier { * @param {LinkMatcherOptions} [options] Options for the link matcher. * @return {number} The ID of the new matcher, this can be used to deregister. */ - public registerLinkMatcher(regex: RegExp, handler: LinkHandler, options: LinkMatcherOptions = {}): number { + public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: LinkMatcherOptions = {}): number { if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { throw new Error('handler cannot be falsy'); } @@ -161,7 +159,7 @@ export class Linkifier { * @param {handler} handler The handler to trigger when the link is triggered. * @return The link element if it was added, otherwise undefined. */ - private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkHandler): HTMLElement { + private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkMatcherHandler): HTMLElement { // Iterate over nodes as we want to consider text nodes const nodes = this._rows[rowIndex].childNodes; for (let i = 0; i < nodes.length; i++) { @@ -210,7 +208,7 @@ export class Linkifier { * @param {string} uri The uri of the link. * @return {HTMLAnchorElement} The link. */ - private _createAnchorElement(uri: string, handler: LinkHandler): HTMLAnchorElement { + private _createAnchorElement(uri: string, handler: LinkMatcherHandler): HTMLAnchorElement { const element = document.createElement('a'); element.textContent = uri; if (handler) { @@ -283,4 +281,11 @@ export class Linkifier { this._replaceNode(node, leftTextNode, newNode, rightTextNode); } } + + public static setTimeBeforeLinkifyForTest(time: number) { + // This is necessary since it's needs to be used in PhantomJS. Ideally the + // time variable would be a protected static member and a TestLinkifier + // would expose it for the test. + TIME_BEFORE_LINKIFY = time; + } } diff --git a/src/Types.ts b/src/Types.ts index 1eafa101..038a1f7a 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -2,4 +2,5 @@ * @license MIT */ +export type LinkMatcherHandler = (uri: string) => void; export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; diff --git a/src/xterm.js b/src/xterm.js index 69eb0a1f..4d5f0205 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2302,6 +2302,7 @@ Terminal.inherits = inherits; // Expose for Phantom.JS tests Terminal.CharMeasure = CharMeasure; +Terminal.Linkifier = Linkifier; /** * Adds an event listener to the terminal. diff --git a/test-harness.html b/test-harness.html index 8c5f0b30..bad4d36e 100644 --- a/test-harness.html +++ b/test-harness.html @@ -14,6 +14,7 @@ assert = chai.assert + - - - - - - - - From efac5293c0bff80c6011b98616821f67c5a692d1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Mar 2017 09:37:16 -0800 Subject: [PATCH 157/211] Use text cursor for invalid links Part of #570 --- src/xterm.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.css b/src/xterm.css index 0401e607..b7f120f9 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -82,7 +82,7 @@ } .terminal a.xterm-invalid-link:hover { - cursor: default; + cursor: text; text-decoration: none; } From dcffaf1c8c4d0c78c22e65eb59f13a5a841eef1a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 1 Mar 2017 09:38:59 -0800 Subject: [PATCH 158/211] Ensure linkElement exists before firing validation callback --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index f8b8ca89..38b7e286 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -141,7 +141,7 @@ export class Linkifier { if (uri) { const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler); // Fire validation callback - if (matcher.validationCallback) { + if (linkElement && matcher.validationCallback) { matcher.validationCallback(uri, isValid => { if (!isValid) { linkElement.classList.add(INVALID_LINK_CLASS); From 7ac4f1a9bec041dd6e04e6ee39efbb73a73a5bae Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 2 Mar 2017 11:25:27 -0800 Subject: [PATCH 159/211] Implement link matcher priorities Fixes #549 --- src/Interfaces.ts | 6 ++++++ src/Linkifier.test.ts | 27 ++++++++++++++++++++++++-- src/Linkifier.ts | 45 ++++++++++++++++++++++++++++++------------- src/Types.ts | 8 ++++++++ 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index d2f8e872..ca228ce0 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -85,6 +85,12 @@ export interface LinkMatcherOptions { * false if invalid. */ validationCallback?: LinkMatcherValidationCallback; + /** + * The priority of the link matcher, this defines the order in which the link + * matcher is evaluated relative to others, from highest to lowest. The + * default value is 0. + */ + priority?: number; } /** diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index b1c1541d..012b1b68 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -5,12 +5,15 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; import { ITerminal, ILinkifier } from './Interfaces'; import { Linkifier } from './Linkifier'; +import { LinkMatcher } from './Types'; class TestLinkifier extends Linkifier { constructor(document: Document, rows: HTMLElement[]) { Linkifier.TIME_BEFORE_LINKIFY = 0; super(document, rows); } + + public get linkMatchers(): LinkMatcher[] { return this._linkMatchers; } } describe('Linkifier', () => { @@ -19,14 +22,14 @@ describe('Linkifier', () => { let container: HTMLElement; let rows: HTMLElement[]; - let linkifier: ILinkifier; + let linkifier: TestLinkifier; beforeEach(done => { rows = []; jsdom.env('', (err, w) => { window = w; document = window.document; - linkifier = new Linkifier(document, rows); + linkifier = new TestLinkifier(document, rows); container = document.createElement('div'); document.body.appendChild(container); done(); @@ -73,4 +76,24 @@ describe('Linkifier', () => { setTimeout(() => done(), 10); }); }); + + describe('priority', () => { + it('should order the list from highest priority to lowest #1', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 1 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: -1 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [aId, 0, bId]); + }); + + it('should order the list from highest priority to lowest #2', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: -1 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 1 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [bId, 0, aId]); + }); + + it('should order items of equal priority in the order they are added', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 0 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 0 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [0, aId, bId]); + }); + }); }); diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 0b144cfd..e1b52cac 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -3,15 +3,7 @@ */ import { LinkMatcherOptions } from './Interfaces'; -import { LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; - -type LinkMatcher = { - id: number, - regex: RegExp, - handler: LinkMatcherHandler, - matchIndex?: number, - validationCallback?: LinkMatcherValidationCallback; -}; +import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; const INVALID_LINK_CLASS = 'xterm-invalid-link'; @@ -50,10 +42,11 @@ export class Linkifier { */ protected static TIME_BEFORE_LINKIFY = 200; + protected _linkMatchers: LinkMatcher[]; + private _document: Document; private _rows: HTMLElement[]; private _rowTimeoutIds: number[]; - private _linkMatchers: LinkMatcher[]; private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; constructor(document: Document, rows: HTMLElement[]) { @@ -105,12 +98,39 @@ export class Linkifier { regex, handler, matchIndex: options.matchIndex, - validationCallback: options.validationCallback + validationCallback: options.validationCallback, + priority: options.priority || 0 }; - this._linkMatchers.push(matcher); + this._addLinkMatcherToList(matcher); return matcher.id; } + /** + * Inserts a link matcher to the list in the correct position based on the + * priority of each link matcher. New link matchers of equal priority are + * considered after older link matchers. + * @param matcher The link matcher to be added. + */ + private _addLinkMatcherToList(matcher: LinkMatcher): void { + if (this._linkMatchers.length === 0) { + this._linkMatchers.push(matcher); + return; + } + + for (let i = this._linkMatchers.length - 1; i >= 0; i--) { + if (matcher.priority === this._linkMatchers[i].priority) { + this._linkMatchers.splice(i + 1, 0, matcher); + return; + } + } + + if (matcher.priority > this._linkMatchers[0].priority) { + this._linkMatchers.splice(0, 0, matcher); + } else { + this._linkMatchers.push(matcher); + } + } + /** * Deregisters a link matcher if it has been registered. * @param {number} matcherId The link matcher's ID (returned after register) @@ -137,7 +157,6 @@ export class Linkifier { return; } const text = row.textContent; - // TODO: Onl execute handler if isValid for (let i = 0; i < this._linkMatchers.length; i++) { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); diff --git a/src/Types.ts b/src/Types.ts index 038a1f7a..2dbb47ef 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -2,5 +2,13 @@ * @license MIT */ +export type LinkMatcher = { + id: number, + regex: RegExp, + handler: LinkMatcherHandler, + matchIndex?: number, + validationCallback?: LinkMatcherValidationCallback, + priority?: number +}; export type LinkMatcherHandler = (uri: string) => void; export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; From 78d5fc95062e77fa6061b14b3b924168b8783893 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 2 Mar 2017 12:05:34 -0800 Subject: [PATCH 160/211] Fix bug with priority --- src/Linkifier.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index e1b52cac..7aab1ef3 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -118,17 +118,13 @@ export class Linkifier { } for (let i = this._linkMatchers.length - 1; i >= 0; i--) { - if (matcher.priority === this._linkMatchers[i].priority) { + if (matcher.priority <= this._linkMatchers[i].priority) { this._linkMatchers.splice(i + 1, 0, matcher); return; } } - if (matcher.priority > this._linkMatchers[0].priority) { - this._linkMatchers.splice(0, 0, matcher); - } else { - this._linkMatchers.push(matcher); - } + this._linkMatchers.splice(0, 0, matcher); } /** From c7b4c2beaf7cb26a7856a1a4d84d6a912fccd5e5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 2 Mar 2017 17:33:58 -0800 Subject: [PATCH 161/211] Require ctrl for link clicks Fixes #578 --- src/Linkifier.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 0b144cfd..41a362b5 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -218,9 +218,13 @@ export class Linkifier { const element = this._document.createElement('a'); element.textContent = uri; if (handler) { - element.addEventListener('click', () => { - // Only execute the handler if the link is not flagged as invalid - if (!element.classList.contains(INVALID_LINK_CLASS)) { + element.addEventListener('click', (event: KeyboardEvent) => { + // Don't execute the handler if the link is flagged as invalid + if (element.classList.contains(INVALID_LINK_CLASS)) { + return; + } + // Require ctrl on click + if (event.ctrlKey) { handler(uri); } }); @@ -228,6 +232,13 @@ export class Linkifier { element.href = uri; // Force link on another tab so work is not lost element.target = '_blank'; + element.addEventListener('click', (event: KeyboardEvent) => { + // Require ctrl on click + if (!event.ctrlKey) { + event.preventDefault(); + return false; + } + }); } return element; } From 012051c1db693b72bb9fea2b61a3590bd2accb54 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 2 Mar 2017 17:35:10 -0800 Subject: [PATCH 162/211] Fix matchIndex on http --- src/Linkifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 1218bdb6..23c68063 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -54,7 +54,7 @@ export class Linkifier { this._rows = rows; this._rowTimeoutIds = []; this._linkMatchers = []; - this.registerLinkMatcher(strictUrlRegex, null, 1); + this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); } /** From 43cb4f471fb69ec1bd7d5f0bf99fe867c8056d56 Mon Sep 17 00:00:00 2001 From: yutaka Date: Fri, 3 Mar 2017 07:57:05 +0000 Subject: [PATCH 163/211] Set charMeasure.height values to each row height --- src/xterm.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index a08e9dd1..8385b601 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -562,6 +562,7 @@ Terminal.bindKeys = function(term) { Terminal.prototype.insertRow = function (row) { if (typeof row != 'object') { row = document.createElement('div'); + row.style.height = this.charMeasure.height + 'px'; } this.rowContainer.appendChild(row); @@ -642,17 +643,18 @@ Terminal.prototype.open = function(parent) { this.charSizeStyleElement = document.createElement('style'); this.helperContainer.appendChild(this.charSizeStyleElement); + this.charMeasure = new CharMeasure(document, this.helperContainer); + this.charMeasure.on('charsizechanged', function () { + self.updateCharSizeCSS(); + self.updateRowHeight(); + }); + this.charMeasure.measure(); + for (; i < this.rows; i++) { this.insertRow(); } this.parent.appendChild(this.element); - this.charMeasure = new CharMeasure(document, this.helperContainer); - this.charMeasure.on('charsizechanged', function () { - self.updateCharSizeCSS(); - }); - this.charMeasure.measure(); - this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); this.renderer = new Renderer(this); @@ -714,6 +716,15 @@ Terminal.prototype.updateCharSizeCSS = function() { this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}'; } +/** + * Updates the height for each rows + */ +Terminal.prototype.updateRowHeight = function() { + for (var i = 0; i < this.children.length; ++i) { + this.children[i].style.height = this.charMeasure.height + 'px'; + } +} + /** * XTerm mouse events * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking From 15a867d2b702cf20d50a254521197b2ea52087a8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 3 Mar 2017 12:37:34 -0800 Subject: [PATCH 164/211] Support cmd+click on mac --- src/Linkifier.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 23c68063..93248c30 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -2,6 +2,7 @@ * @license MIT */ +import { isMac } from './utils/Browser'; import { LinkMatcherOptions } from './Interfaces'; import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; @@ -239,7 +240,7 @@ export class Linkifier { return; } // Require ctrl on click - if (event.ctrlKey) { + if (isMac ? event.metaKey : event.ctrlKey) { handler(uri); } }); @@ -249,7 +250,7 @@ export class Linkifier { element.target = '_blank'; element.addEventListener('click', (event: KeyboardEvent) => { // Require ctrl on click - if (!event.ctrlKey) { + if (isMac ? !event.metaKey : !event.ctrlKey) { event.preventDefault(); return false; } From 43558fa1dc94f8f21ca2d93dcab18ca89ae03c0b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 3 Mar 2017 23:40:36 +0200 Subject: [PATCH 165/211] Fix demo: wrong pid on windows #567 --- demo/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/app.js b/demo/app.js index 3439ea99..8637dad8 100644 --- a/demo/app.js +++ b/demo/app.js @@ -69,7 +69,7 @@ app.ws('/terminals/:pid', function (ws, req) { term.write(msg); }); ws.on('close', function () { - process.kill(term.pid); + term.kill(); console.log('Closed terminal ' + term.pid); // Clean things up delete terminals[term.pid]; From 1ecc5674ac92d6876ac63b552dd49bbc46f06feb Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 4 Mar 2017 14:01:34 -0800 Subject: [PATCH 166/211] Add fail handler --- src/Interfaces.ts | 6 ++++++ src/Linkifier.ts | 20 ++++++++++++++------ src/Types.ts | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index ca228ce0..27ea4d4c 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -85,6 +85,12 @@ export interface LinkMatcherOptions { * false if invalid. */ validationCallback?: LinkMatcherValidationCallback; + /** + * A callback that fires when a link click fails due to ctrl or cmd (mac) not + * being pressed. This allows hinting to the user after a likely failed + * click. + */ + clickFailCallback?: (event: MouseEvent) => any; /** * The priority of the link matcher, this defines the order in which the link * matcher is evaluated relative to others, from highest to lowest. The diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 93248c30..6667af0c 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -100,6 +100,7 @@ export class Linkifier { handler, matchIndex: options.matchIndex, validationCallback: options.validationCallback, + clickFailCallback: options.clickFailCallback, priority: options.priority || 0 }; this._addLinkMatcherToList(matcher); @@ -158,7 +159,7 @@ export class Linkifier { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { - const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler); + const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.clickFailCallback); // Fire validation callback if (linkElement && matcher.validationCallback) { matcher.validationCallback(uri, isValid => { @@ -180,14 +181,14 @@ export class Linkifier { * @param {handler} handler The handler to trigger when the link is triggered. * @return The link element if it was added, otherwise undefined. */ - private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkMatcherHandler): HTMLElement { + private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkMatcherHandler, clickFailHandler?: (event: MouseEvent) => any): HTMLElement { // Iterate over nodes as we want to consider text nodes const nodes = this._rows[rowIndex].childNodes; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; const searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { - const linkElement = this._createAnchorElement(uri, handler); + const linkElement = this._createAnchorElement(uri, handler, clickFailHandler); if (node.textContent.length === uri.length) { // Matches entire string @@ -230,11 +231,11 @@ export class Linkifier { * @param {string} uri The uri of the link. * @return {HTMLAnchorElement} The link. */ - private _createAnchorElement(uri: string, handler: LinkMatcherHandler): HTMLAnchorElement { + private _createAnchorElement(uri: string, handler: LinkMatcherHandler, failHandler: (event: MouseEvent) => any): HTMLAnchorElement { const element = this._document.createElement('a'); element.textContent = uri; if (handler) { - element.addEventListener('click', (event: KeyboardEvent) => { + element.addEventListener('click', (event: MouseEvent) => { // Don't execute the handler if the link is flagged as invalid if (element.classList.contains(INVALID_LINK_CLASS)) { return; @@ -242,15 +243,22 @@ export class Linkifier { // Require ctrl on click if (isMac ? event.metaKey : event.ctrlKey) { handler(uri); + } else { + if (failHandler) { + failHandler(event); + } } }); } else { element.href = uri; // Force link on another tab so work is not lost element.target = '_blank'; - element.addEventListener('click', (event: KeyboardEvent) => { + element.addEventListener('click', (event: MouseEvent) => { // Require ctrl on click if (isMac ? !event.metaKey : !event.ctrlKey) { + if (failHandler) { + failHandler(event); + } event.preventDefault(); return false; } diff --git a/src/Types.ts b/src/Types.ts index 2dbb47ef..d3e99dd0 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -8,6 +8,7 @@ export type LinkMatcher = { handler: LinkMatcherHandler, matchIndex?: number, validationCallback?: LinkMatcherValidationCallback, + clickFailCallback?: (event: MouseEvent) => any, priority?: number }; export type LinkMatcherHandler = (uri: string) => void; From 5e2791f981279b539615e49d614902363d3138c9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 4 Mar 2017 14:01:40 -0800 Subject: [PATCH 167/211] Revert "Add fail handler" This reverts commit 1ecc5674ac92d6876ac63b552dd49bbc46f06feb. --- src/Interfaces.ts | 6 ------ src/Linkifier.ts | 20 ++++++-------------- src/Types.ts | 1 - 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 27ea4d4c..ca228ce0 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -85,12 +85,6 @@ export interface LinkMatcherOptions { * false if invalid. */ validationCallback?: LinkMatcherValidationCallback; - /** - * A callback that fires when a link click fails due to ctrl or cmd (mac) not - * being pressed. This allows hinting to the user after a likely failed - * click. - */ - clickFailCallback?: (event: MouseEvent) => any; /** * The priority of the link matcher, this defines the order in which the link * matcher is evaluated relative to others, from highest to lowest. The diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 6667af0c..93248c30 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -100,7 +100,6 @@ export class Linkifier { handler, matchIndex: options.matchIndex, validationCallback: options.validationCallback, - clickFailCallback: options.clickFailCallback, priority: options.priority || 0 }; this._addLinkMatcherToList(matcher); @@ -159,7 +158,7 @@ export class Linkifier { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { - const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.clickFailCallback); + const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler); // Fire validation callback if (linkElement && matcher.validationCallback) { matcher.validationCallback(uri, isValid => { @@ -181,14 +180,14 @@ export class Linkifier { * @param {handler} handler The handler to trigger when the link is triggered. * @return The link element if it was added, otherwise undefined. */ - private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkMatcherHandler, clickFailHandler?: (event: MouseEvent) => any): HTMLElement { + private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkMatcherHandler): HTMLElement { // Iterate over nodes as we want to consider text nodes const nodes = this._rows[rowIndex].childNodes; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; const searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { - const linkElement = this._createAnchorElement(uri, handler, clickFailHandler); + const linkElement = this._createAnchorElement(uri, handler); if (node.textContent.length === uri.length) { // Matches entire string @@ -231,11 +230,11 @@ export class Linkifier { * @param {string} uri The uri of the link. * @return {HTMLAnchorElement} The link. */ - private _createAnchorElement(uri: string, handler: LinkMatcherHandler, failHandler: (event: MouseEvent) => any): HTMLAnchorElement { + private _createAnchorElement(uri: string, handler: LinkMatcherHandler): HTMLAnchorElement { const element = this._document.createElement('a'); element.textContent = uri; if (handler) { - element.addEventListener('click', (event: MouseEvent) => { + element.addEventListener('click', (event: KeyboardEvent) => { // Don't execute the handler if the link is flagged as invalid if (element.classList.contains(INVALID_LINK_CLASS)) { return; @@ -243,22 +242,15 @@ export class Linkifier { // Require ctrl on click if (isMac ? event.metaKey : event.ctrlKey) { handler(uri); - } else { - if (failHandler) { - failHandler(event); - } } }); } else { element.href = uri; // Force link on another tab so work is not lost element.target = '_blank'; - element.addEventListener('click', (event: MouseEvent) => { + element.addEventListener('click', (event: KeyboardEvent) => { // Require ctrl on click if (isMac ? !event.metaKey : !event.ctrlKey) { - if (failHandler) { - failHandler(event); - } event.preventDefault(); return false; } diff --git a/src/Types.ts b/src/Types.ts index d3e99dd0..2dbb47ef 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -8,7 +8,6 @@ export type LinkMatcher = { handler: LinkMatcherHandler, matchIndex?: number, validationCallback?: LinkMatcherValidationCallback, - clickFailCallback?: (event: MouseEvent) => any, priority?: number }; export type LinkMatcherHandler = (uri: string) => void; From aafb5333b9af22c28bf9143dc90d9ce60e3f03dd Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 4 Mar 2017 14:08:05 -0800 Subject: [PATCH 168/211] Give event to handler --- src/Linkifier.ts | 18 +++++++----------- src/Types.ts | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 93248c30..d144fefc 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -92,7 +92,7 @@ export class Linkifier { */ public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: LinkMatcherOptions = {}): number { if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { - throw new Error('handler cannot be falsy'); + throw new Error('handler must be defined'); } const matcher: LinkMatcher = { id: this._nextLinkMatcherId++, @@ -234,25 +234,21 @@ export class Linkifier { const element = this._document.createElement('a'); element.textContent = uri; if (handler) { - element.addEventListener('click', (event: KeyboardEvent) => { + element.addEventListener('click', (event: MouseEvent) => { // Don't execute the handler if the link is flagged as invalid if (element.classList.contains(INVALID_LINK_CLASS)) { return; } - // Require ctrl on click - if (isMac ? event.metaKey : event.ctrlKey) { - handler(uri); - } + + return handler(event, uri); }); } else { element.href = uri; // Force link on another tab so work is not lost element.target = '_blank'; - element.addEventListener('click', (event: KeyboardEvent) => { - // Require ctrl on click - if (isMac ? !event.metaKey : !event.ctrlKey) { - event.preventDefault(); - return false; + element.addEventListener('click', (event: MouseEvent) => { + if (handler) { + return handler(event, uri); } }); } diff --git a/src/Types.ts b/src/Types.ts index 2dbb47ef..634e2fdc 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -10,5 +10,5 @@ export type LinkMatcher = { validationCallback?: LinkMatcherValidationCallback, priority?: number }; -export type LinkMatcherHandler = (uri: string) => void; +export type LinkMatcherHandler = (event: MouseEvent, uri: string) => void; export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; From ab34d53d6b1b0c941e29475121adb567e9ae54bf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 4 Mar 2017 14:09:13 -0800 Subject: [PATCH 169/211] Remove unused import --- src/Linkifier.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index d144fefc..8f011cb2 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -2,7 +2,6 @@ * @license MIT */ -import { isMac } from './utils/Browser'; import { LinkMatcherOptions } from './Interfaces'; import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; From 1f518b0b455109a193a936f520e4271db966ee68 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 4 Mar 2017 14:44:11 -0800 Subject: [PATCH 170/211] Allow http link handler to fallback to standard handler --- src/Linkifier.ts | 21 ++++++++++----------- src/Types.ts | 2 +- src/xterm.js | 1 - 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 8f011cb2..1cdf0f4a 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -229,19 +229,10 @@ export class Linkifier { * @param {string} uri The uri of the link. * @return {HTMLAnchorElement} The link. */ - private _createAnchorElement(uri: string, handler: LinkMatcherHandler): HTMLAnchorElement { + private _createAnchorElement(uri: string, handler: LinkMatcherHandler, isHypertextLinkHandler: boolean): HTMLAnchorElement { const element = this._document.createElement('a'); element.textContent = uri; - if (handler) { - element.addEventListener('click', (event: MouseEvent) => { - // Don't execute the handler if the link is flagged as invalid - if (element.classList.contains(INVALID_LINK_CLASS)) { - return; - } - - return handler(event, uri); - }); - } else { + if (isHypertextLinkHandler) { element.href = uri; // Force link on another tab so work is not lost element.target = '_blank'; @@ -250,6 +241,14 @@ export class Linkifier { return handler(event, uri); } }); + } else { + element.addEventListener('click', (event: MouseEvent) => { + // Don't execute the handler if the link is flagged as invalid + if (element.classList.contains(INVALID_LINK_CLASS)) { + return; + } + return handler(event, uri); + }); } return element; } diff --git a/src/Types.ts b/src/Types.ts index 634e2fdc..9e8cd762 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -10,5 +10,5 @@ export type LinkMatcher = { validationCallback?: LinkMatcherValidationCallback, priority?: number }; -export type LinkMatcherHandler = (event: MouseEvent, uri: string) => void; +export type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void; export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; diff --git a/src/xterm.js b/src/xterm.js index a08e9dd1..37c00ed8 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1295,7 +1295,6 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { this.refresh(0, this.rows - 1); } - /** * Registers a link matcher, allowing custom link patterns to be matched and * handled. From 235ae2fbb98ac95efc4f55517d755f148462c8a3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 4 Mar 2017 15:02:08 -0800 Subject: [PATCH 171/211] Fix http link handler logic --- src/Linkifier.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 1cdf0f4a..a34edbc2 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -157,7 +157,7 @@ export class Linkifier { const matcher = this._linkMatchers[i]; const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); if (uri) { - const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler); + const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID); // Fire validation callback if (linkElement && matcher.validationCallback) { matcher.validationCallback(uri, isValid => { @@ -179,14 +179,14 @@ export class Linkifier { * @param {handler} handler The handler to trigger when the link is triggered. * @return The link element if it was added, otherwise undefined. */ - private _doLinkifyRow(rowIndex: number, uri: string, handler?: LinkMatcherHandler): HTMLElement { + private _doLinkifyRow(rowIndex: number, uri: string, handler: LinkMatcherHandler, isHttpLinkMatcher: boolean): HTMLElement { // Iterate over nodes as we want to consider text nodes const nodes = this._rows[rowIndex].childNodes; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; const searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { - const linkElement = this._createAnchorElement(uri, handler); + const linkElement = this._createAnchorElement(uri, handler, isHttpLinkMatcher); if (node.textContent.length === uri.length) { // Matches entire string From dc3a136704e1a33aac72317e8385258399e94da6 Mon Sep 17 00:00:00 2001 From: Aleksandr Andrienko Date: Tue, 28 Feb 2017 11:30:47 +0200 Subject: [PATCH 172/211] Use tsconfig.json data in gulpfile.js instead of hardcoded values. Use tsconfig.json data in gulpfile.js instead of hardcoded values. Little code clean up Signed-off-by: Aleksandr Andrienko --- gulpfile.js | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 2e58d26c..feaa3dcf 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -13,27 +13,28 @@ const ts = require('gulp-typescript'); let buildDir = process.env.BUILD_DIR || 'build'; - +let tsProject = ts.createProject('tsconfig.json'); +let srcDir = tsProject.config.compilerOptions.rootDir; +let outDir = tsProject.config.compilerOptions.outDir; /** * Compile TypeScript sources to JavaScript files and create a source map file for each TypeScript * file compiled. */ gulp.task('tsc', function () { - // Remove the lib/ directory to prevent confusion if files were deleted in src/ - fs.emptyDirSync('lib'); + // Remove the ${outDir}/ directory to prevent confusion if files were deleted in ${srcDir}/ + fs.emptyDirSync(`${outDir}`); - // Build all TypeScript files (including tests) to lib/, based on the configuration defined in + // Build all TypeScript files (including tests) to ${outDir}/, based on the configuration defined in // `tsconfig.json`. - let tsProject = ts.createProject('tsconfig.json'); let tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject()); - let tsc = tsResult.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest('lib')); + let tsc = tsResult.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(outDir)); - // Copy all addons from src/ to lib/ - let copyAddons = gulp.src('src/addons/**/*').pipe(gulp.dest('lib/addons')); + // Copy all addons from ${srcDir}/ to ${outDir}/ + let copyAddons = gulp.src(`${srcDir}/addons/**/*`).pipe(gulp.dest(`${outDir}/addons`)); - // Copy stylesheets from src/ to lib/ - let copyStylesheets = gulp.src('src/**/*.css').pipe(gulp.dest('lib')); + // Copy stylesheets from ${srcDir}/ to ${outDir}/ + let copyStylesheets = gulp.src(`${srcDir}/**/*.css`).pipe(gulp.dest(outDir)); return merge(tsc, copyAddons, copyStylesheets); }); @@ -49,7 +50,7 @@ gulp.task('browserify', ['tsc'], function() { let browserifyOptions = { basedir: buildDir, debug: true, - entries: ['../lib/xterm.js'], + entries: [`../${outDir}/xterm.js`], standalone: 'Terminal', cache: {}, packageCache: {} @@ -62,17 +63,17 @@ gulp.task('browserify', ['tsc'], function() { .pipe(sourcemaps.write('./')) .pipe(gulp.dest(buildDir)); - // Copy all add-ons from lib/ to buildDir - let copyAddons = gulp.src('lib/addons/**/*').pipe(gulp.dest(`${buildDir}/addons`)); + // Copy all add-ons from ${outDir}/ to buildDir + let copyAddons = gulp.src(`${outDir}/addons/**/*`).pipe(gulp.dest(`${buildDir}/addons`)); - // Copy stylesheets from src/ to lib/ - let copyStylesheets = gulp.src('lib/**/*.css').pipe(gulp.dest(buildDir)); + // Copy stylesheets from ${outDir}/ to ${buildDir}/ + let copyStylesheets = gulp.src(`${outDir}/**/*.css`).pipe(gulp.dest(buildDir)); return merge(bundleStream, copyAddons, copyStylesheets); }); gulp.task('instrument-test', function () { - return gulp.src(['lib/**/*.js']) + return gulp.src([`${outDir}/**/*.js`]) // Covering files .pipe(istanbul()) // Force `require` to return covered files @@ -80,7 +81,7 @@ gulp.task('instrument-test', function () { }); gulp.task('mocha', ['instrument-test'], function () { - return gulp.src(['lib/*test.js', 'lib/**/*test.js'], {read: false}) + return gulp.src([`${outDir}/*test.js`, `${outDir}/**/*test.js`], {read: false}) .pipe(mocha()) .pipe(istanbul.writeReports()); }); @@ -88,11 +89,11 @@ gulp.task('mocha', ['instrument-test'], function () { /** * Use `sorcery` to resolve the source map chain and point back to the TypeScript files. * (Without this task the source maps produced for the JavaScript bundle points into the - * compiled JavaScript files in lib/). + * compiled JavaScript files in ${outDir}/). */ gulp.task('sorcery', ['browserify'], function () { var chain = sorcery.loadSync(`${buildDir}/xterm.js`); - var map = chain.apply(); + chain.apply(); chain.writeSync(); }); From 3d721a95bb31af064d9ab007aca03d128f4d55a0 Mon Sep 17 00:00:00 2001 From: Aleksandr Andrienko Date: Mon, 6 Mar 2017 13:13:11 +0200 Subject: [PATCH 173/211] Clean up tsconfig.json. 'include' field in the tsconfig.json defines source scope (top level of this scope is "src" folder), so we do not need 'exclude' folders in the root of the project, because this folders had already excluded by 'include' scope. Signed-off-by: Aleksandr Andrienko --- tsconfig.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index c9e7fd46..2e9703dd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,13 +12,6 @@ "src/**/*" ], "exclude": [ - "src/addons/**/*", - "build", - "demo", - "dist", - "out", - "test", - "node_modules", - "docs" + "src/addons/**/*" ] } From b1619e42fd5a83cfecbb0959f781853c60216fd3 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Tue, 7 Mar 2017 09:38:48 +0000 Subject: [PATCH 174/211] Bump version to 2.4.0 Signed-off-by: Paris Kasidiaris --- AUTHORS | 3 + bower.json | 2 +- dist/addons/fit/fit.js | 7 +- dist/xterm.css | 22 +++- dist/xterm.js | 277 ++++++++++++++++++++++++++++++++++++++--- dist/xterm.js.map | 2 +- package.json | 2 +- 7 files changed, 289 insertions(+), 26 deletions(-) diff --git a/AUTHORS b/AUTHORS index 345e8d75..b0ca2d2f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,9 +13,11 @@ Benjamin Fischer Bill Church Bob Reid bottleofwater +Brian Mock Carson Anderson Christian Budde Christensen Christopher Jeffrey +coderaiser Daniel Imms Daniel Risacher Dan Kaplun @@ -28,6 +30,7 @@ Jean Bruenn Jörg Breitbart Lucian Buzzo Maël Nison +Martin Wang Mikko Karvonen Paris Kasidiaris Paris Kasidiaris diff --git a/bower.json b/bower.json index ad780f43..dcac3aa4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "xterm.js", - "version": "2.3.2", + "version": "2.4.0", "ignore": ["demo", "test", ".gitignore"], "main": [ "dist/xterm.js", diff --git a/dist/addons/fit/fit.js b/dist/addons/fit/fit.js index cacd9202..11fc6eb7 100644 --- a/dist/addons/fit/fit.js +++ b/dist/addons/fit/fit.js @@ -32,6 +32,9 @@ var exports = {}; exports.proposeGeometry = function (term) { + if (!term.element.parentElement) { + return null; + } var parentElementStyle = window.getComputedStyle(term.element.parentElement), parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), @@ -66,7 +69,9 @@ exports.fit = function (term) { var geometry = exports.proposeGeometry(term); - term.resize(geometry.cols, geometry.rows); + if (geometry) { + term.resize(geometry.cols, geometry.rows); + } }; Xterm.prototype.proposeGeometry = function () { diff --git a/dist/xterm.css b/dist/xterm.css index 27638e14..b7f120f9 100644 --- a/dist/xterm.css +++ b/dist/xterm.css @@ -71,6 +71,21 @@ resize: none; } +.terminal a { + color: inherit; + text-decoration: none; +} + +.terminal a:hover { + cursor: pointer; + text-decoration: underline; +} + +.terminal a.xterm-invalid-link:hover { + cursor: text; + text-decoration: none; +} + .terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { background-color: #fff; color: #000; @@ -87,13 +102,10 @@ } @keyframes xterm-cursor-blink { - 0% { - background-color: #fff; - color: #000; - } + 0% { } 50% { background-color: transparent; - color: #FFF; + color: inherit; } } diff --git a/dist/xterm.js b/dist/xterm.js index d2e5dacd..e1d81b72 100644 --- a/dist/xterm.js +++ b/dist/xterm.js @@ -1163,7 +1163,7 @@ var InputHandler = (function () { this._terminal.cursorHidden = false; this._terminal.insertMode = false; this._terminal.originMode = false; - this._terminal.wraparoundMode = false; + this._terminal.wraparoundMode = true; this._terminal.applicationKeypad = false; this._terminal.viewport.syncScrollArea(); this._terminal.applicationCursor = false; @@ -1314,6 +1314,214 @@ var wcwidth = (function (opts) { },{"./Charsets":1,"./EscapeSequences":3}],6:[function(require,module,exports){ "use strict"; +var INVALID_LINK_CLASS = 'xterm-invalid-link'; +var protocolClause = '(https?:\\/\\/)'; +var domainCharacterSet = '[\\da-z\\.-]+'; +var negatedDomainCharacterSet = '[^\\da-z\\.-]+'; +var domainBodyClause = '(' + domainCharacterSet + ')'; +var tldClause = '([a-z\\.]{2,6})'; +var ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; +var localHostClause = '(localhost)'; +var portClause = '(:\\d{1,5})'; +var hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; +var pathClause = '(\\/[\\/\\w\\.\\-%]*)*'; +var queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;\\=\\.\\-]*'; +var queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; +var hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; +var negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; +var bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause; +var start = '(?:^|' + negatedDomainCharacterSet + ')('; +var end = ')($|' + negatedPathCharacterSet + ')'; +var strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); +var HYPERTEXT_LINK_MATCHER_ID = 0; +var Linkifier = (function () { + function Linkifier(document, rows) { + this._nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; + this._document = document; + this._rows = rows; + this._rowTimeoutIds = []; + this._linkMatchers = []; + this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); + } + Linkifier.prototype.linkifyRow = function (rowIndex) { + var timeoutId = this._rowTimeoutIds[rowIndex]; + if (timeoutId) { + clearTimeout(timeoutId); + } + this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), Linkifier.TIME_BEFORE_LINKIFY); + }; + Linkifier.prototype.attachHypertextLinkHandler = function (handler) { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; + }; + Linkifier.prototype.registerLinkMatcher = function (regex, handler, options) { + if (options === void 0) { options = {}; } + if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { + throw new Error('handler must be defined'); + } + var matcher = { + id: this._nextLinkMatcherId++, + regex: regex, + handler: handler, + matchIndex: options.matchIndex, + validationCallback: options.validationCallback, + priority: options.priority || 0 + }; + this._addLinkMatcherToList(matcher); + return matcher.id; + }; + Linkifier.prototype._addLinkMatcherToList = function (matcher) { + if (this._linkMatchers.length === 0) { + this._linkMatchers.push(matcher); + return; + } + for (var i = this._linkMatchers.length - 1; i >= 0; i--) { + if (matcher.priority <= this._linkMatchers[i].priority) { + this._linkMatchers.splice(i + 1, 0, matcher); + return; + } + } + this._linkMatchers.splice(0, 0, matcher); + }; + Linkifier.prototype.deregisterLinkMatcher = function (matcherId) { + for (var i = 1; i < this._linkMatchers.length; i++) { + if (this._linkMatchers[i].id === matcherId) { + this._linkMatchers.splice(i, 1); + return true; + } + } + return false; + }; + Linkifier.prototype._linkifyRow = function (rowIndex) { + var row = this._rows[rowIndex]; + if (!row) { + return; + } + var text = row.textContent; + var _loop_1 = function (i) { + var matcher = this_1._linkMatchers[i]; + var uri = this_1._findLinkMatch(text, matcher.regex, matcher.matchIndex); + if (uri) { + var linkElement_1 = this_1._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID); + if (linkElement_1 && matcher.validationCallback) { + matcher.validationCallback(uri, function (isValid) { + if (!isValid) { + linkElement_1.classList.add(INVALID_LINK_CLASS); + } + }); + } + return { value: void 0 }; + } + }; + var this_1 = this; + for (var i = 0; i < this._linkMatchers.length; i++) { + var state_1 = _loop_1(i); + if (typeof state_1 === "object") + return state_1.value; + } + }; + Linkifier.prototype._doLinkifyRow = function (rowIndex, uri, handler, isHttpLinkMatcher) { + var nodes = this._rows[rowIndex].childNodes; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var searchIndex = node.textContent.indexOf(uri); + if (searchIndex >= 0) { + var linkElement = this._createAnchorElement(uri, handler, isHttpLinkMatcher); + if (node.textContent.length === uri.length) { + if (node.nodeType === 3) { + this._replaceNode(node, linkElement); + } + else { + var element = node; + if (element.nodeName === 'A') { + return; + } + element.innerHTML = ''; + element.appendChild(linkElement); + } + } + else { + this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); + } + return linkElement; + } + } + }; + Linkifier.prototype._findLinkMatch = function (text, regex, matchIndex) { + var match = text.match(regex); + if (!match || match.length === 0) { + return null; + } + return match[typeof matchIndex !== 'number' ? 0 : matchIndex]; + }; + Linkifier.prototype._createAnchorElement = function (uri, handler, isHypertextLinkHandler) { + var element = this._document.createElement('a'); + element.textContent = uri; + if (isHypertextLinkHandler) { + element.href = uri; + element.target = '_blank'; + element.addEventListener('click', function (event) { + if (handler) { + return handler(event, uri); + } + }); + } + else { + element.addEventListener('click', function (event) { + if (element.classList.contains(INVALID_LINK_CLASS)) { + return; + } + return handler(event, uri); + }); + } + return element; + }; + Linkifier.prototype._replaceNode = function (oldNode) { + var newNodes = []; + for (var _i = 1; _i < arguments.length; _i++) { + newNodes[_i - 1] = arguments[_i]; + } + var parent = oldNode.parentNode; + for (var i = 0; i < newNodes.length; i++) { + parent.insertBefore(newNodes[i], oldNode); + } + parent.removeChild(oldNode); + }; + Linkifier.prototype._replaceNodeSubstringWithNode = function (targetNode, newNode, substring, substringIndex) { + var node = targetNode; + if (node.nodeType !== 3) { + node = node.childNodes[0]; + } + if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) { + throw new Error('targetNode must be a text node or only contain a single text node'); + } + var fullText = node.textContent; + if (substringIndex === 0) { + var rightText = fullText.substring(substring.length); + var rightTextNode = this._document.createTextNode(rightText); + this._replaceNode(node, newNode, rightTextNode); + } + else if (substringIndex === targetNode.textContent.length - substring.length) { + var leftText = fullText.substring(0, substringIndex); + var leftTextNode = this._document.createTextNode(leftText); + this._replaceNode(node, leftTextNode, newNode); + } + else { + var leftText = fullText.substring(0, substringIndex); + var leftTextNode = this._document.createTextNode(leftText); + var rightText = fullText.substring(substringIndex + substring.length); + var rightTextNode = this._document.createTextNode(rightText); + this._replaceNode(node, leftTextNode, newNode, rightTextNode); + } + }; + return Linkifier; +}()); +Linkifier.TIME_BEFORE_LINKIFY = 200; +exports.Linkifier = Linkifier; + + + +},{}],7:[function(require,module,exports){ +"use strict"; var EscapeSequences_1 = require("./EscapeSequences"); var Charsets_1 = require("./Charsets"); var normalStateHandler = {}; @@ -1787,7 +1995,7 @@ exports.Parser = Parser; -},{"./Charsets":1,"./EscapeSequences":3}],7:[function(require,module,exports){ +},{"./Charsets":1,"./EscapeSequences":3}],8:[function(require,module,exports){ "use strict"; var MAX_REFRESH_FRAME_SKIP = 5; var FLAGS; @@ -1998,7 +2206,7 @@ function checkBoldBroken(document) { -},{}],8:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ "use strict"; var Viewport = (function () { function Viewport(terminal, viewportElement, scrollArea, charMeasure) { @@ -2075,7 +2283,7 @@ exports.Viewport = Viewport; -},{}],9:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ "use strict"; function prepareTextForClipboard(text) { var space = String.fromCharCode(32), nonBreakingSpace = String.fromCharCode(160), allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'), processedText = text.split('\n').map(function (line) { @@ -2156,7 +2364,7 @@ exports.rightClickHandler = rightClickHandler; -},{}],10:[function(require,module,exports){ +},{}],11:[function(require,module,exports){ "use strict"; var Generic_1 = require("./Generic"); var isNode = (typeof navigator === 'undefined') ? true : false; @@ -2171,7 +2379,7 @@ exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], -},{"./Generic":13}],11:[function(require,module,exports){ +},{"./Generic":14}],12:[function(require,module,exports){ "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -2181,8 +2389,9 @@ var __extends = (this && this.__extends) || function (d, b) { var EventEmitter_js_1 = require("../EventEmitter.js"); var CharMeasure = (function (_super) { __extends(CharMeasure, _super); - function CharMeasure(parentElement) { + function CharMeasure(document, parentElement) { var _this = _super.call(this) || this; + _this._document = document; _this._parentElement = parentElement; return _this; } @@ -2203,11 +2412,12 @@ var CharMeasure = (function (_super) { CharMeasure.prototype.measure = function () { var _this = this; if (!this._measureElement) { - this._measureElement = document.createElement('span'); + this._measureElement = this._document.createElement('span'); this._measureElement.style.position = 'absolute'; this._measureElement.style.top = '0'; this._measureElement.style.left = '-9999em'; this._measureElement.textContent = 'W'; + this._measureElement.setAttribute('aria-hidden', 'true'); this._parentElement.appendChild(this._measureElement); setTimeout(function () { return _this._doMeasure(); }, 0); } @@ -2232,7 +2442,7 @@ exports.CharMeasure = CharMeasure; -},{"../EventEmitter.js":4}],12:[function(require,module,exports){ +},{"../EventEmitter.js":4}],13:[function(require,module,exports){ "use strict"; var CircularList = (function () { function CircularList(maxLength) { @@ -2370,7 +2580,7 @@ exports.CircularList = CircularList; -},{}],13:[function(require,module,exports){ +},{}],14:[function(require,module,exports){ "use strict"; function contains(arr, el) { return arr.indexOf(el) >= 0; @@ -2380,7 +2590,7 @@ exports.contains = contains; -},{}],14:[function(require,module,exports){ +},{}],15:[function(require,module,exports){ "use strict"; var CompositionHelper_1 = require("./CompositionHelper"); var EventEmitter_1 = require("./EventEmitter"); @@ -2391,6 +2601,7 @@ var EscapeSequences_1 = require("./EscapeSequences"); var InputHandler_1 = require("./InputHandler"); var Parser_1 = require("./Parser"); var Renderer_1 = require("./Renderer"); +var Linkifier_1 = require("./Linkifier"); var CharMeasure_1 = require("./utils/CharMeasure"); var Browser = require("./utils/Browser"); var document = (typeof window != 'undefined') ? window.document : null; @@ -2491,6 +2702,8 @@ function Terminal(options) { this.inputHandler = new InputHandler_1.InputHandler(this); this.parser = new Parser_1.Parser(this.inputHandler, this); this.renderer = this.renderer || null; + this.linkifier = this.linkifier || null; + ; this.writeBuffer = []; this.writeInProgress = false; this.xoffSentToCatchUp = false; @@ -2715,6 +2928,9 @@ Terminal.bindKeys = function (term) { on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper)); on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper)); term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper)); + term.on('refresh', function (data) { + term.queueLinkification(data.start, data.end); + }); }; Terminal.prototype.insertRow = function (row) { if (typeof row != 'object') { @@ -2750,6 +2966,7 @@ Terminal.prototype.open = function (parent) { this.rowContainer.classList.add('xterm-rows'); this.element.appendChild(this.rowContainer); this.children = []; + this.linkifier = new Linkifier_1.Linkifier(document, this.children); this.helperContainer = document.createElement('div'); this.helperContainer.classList.add('xterm-helpers'); this.element.appendChild(this.helperContainer); @@ -2776,7 +2993,7 @@ Terminal.prototype.open = function (parent) { this.insertRow(); } this.parent.appendChild(this.element); - this.charMeasure = new CharMeasure_1.CharMeasure(this.helperContainer); + this.charMeasure = new CharMeasure_1.CharMeasure(document, this.helperContainer); this.charMeasure.on('charsizechanged', function () { self.updateCharSizeCSS(); }); @@ -2985,10 +3202,8 @@ Terminal.prototype.bindMouse = function () { ? el.offsetParent : el.parentNode; } - w = self.element.clientWidth; - h = self.element.clientHeight; - x = Math.ceil((x / w) * self.cols); - y = Math.ceil((y / h) * self.rows); + x = Math.ceil(x / self.charMeasure.width); + y = Math.ceil(y / self.charMeasure.height); if (x < 0) x = 0; if (x > self.cols) @@ -3060,6 +3275,13 @@ Terminal.prototype.refresh = function (start, end) { this.renderer.queueRefresh(start, end); } }; +Terminal.prototype.queueLinkification = function (start, end) { + if (this.linkifier) { + for (var i = start; i <= end; i++) { + this.linkifier.linkifyRow(i); + } + } +}; Terminal.prototype.showCursor = function () { if (!this.cursorState) { this.cursorState = 1; @@ -3173,6 +3395,27 @@ Terminal.prototype.writeln = function (data) { Terminal.prototype.attachCustomKeydownHandler = function (customKeydownHandler) { this.customKeydownHandler = customKeydownHandler; }; +Terminal.prototype.attachHypertextLinkHandler = function (handler) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); + } + this.linkifier.attachHypertextLinkHandler(handler); + this.refresh(0, this.rows - 1); +}; +Terminal.prototype.registerLinkMatcher = function (regex, handler, options) { + if (this.linkifier) { + var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options); + this.refresh(0, this.rows - 1); + return matcherId; + } +}; +Terminal.prototype.deregisterLinkMatcher = function (matcherId) { + if (this.linkifier) { + if (this.linkifier.deregisterLinkMatcher(matcherId)) { + this.refresh(0, this.rows - 1); + } + } +}; Terminal.prototype.keyDown = function (ev) { if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) { return false; @@ -3892,6 +4135,6 @@ module.exports = Terminal; -},{"./CompositionHelper":2,"./EscapeSequences":3,"./EventEmitter":4,"./InputHandler":5,"./Parser":6,"./Renderer":7,"./Viewport":8,"./handlers/Clipboard":9,"./utils/Browser":10,"./utils/CharMeasure":11,"./utils/CircularList":12}]},{},[14])(14) +},{"./CompositionHelper":2,"./EscapeSequences":3,"./EventEmitter":4,"./InputHandler":5,"./Linkifier":6,"./Parser":7,"./Renderer":8,"./Viewport":9,"./handlers/Clipboard":10,"./utils/Browser":11,"./utils/CharMeasure":12,"./utils/CircularList":13}]},{},[15])(15) }); //# sourceMappingURL=xterm.js.map diff --git a/dist/xterm.js.map b/dist/xterm.js.map index c20019cd..90021b21 100644 --- a/dist/xterm.js.map +++ b/dist/xterm.js.map @@ -1 +1 @@ -{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n w = self.element.clientWidth;\n h = self.element.clientHeight;\n x = Math.ceil((x / w) * self.cols);\n y = Math.ceil((y / h) * self.rows);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(parentElement: HTMLElement) {\n super();\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n // Perform this async to ensure the CharMeasure is ready.\n setTimeout(() => this.syncScrollArea(), 0);\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = false; // autowrap\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"AcAA;;ADSa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AD3OA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AACA;AAAA;AApNa;;;;;;ADZb;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAAC;;;;;;ADlEA;AAED;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA9Da;;;;;;ADJb;AACA;AASA;AAEA;AAAA;AAAA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAkEA;AAEA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAj7Ca;AAm7Cb;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADriDA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAKA;AACA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAIA;AACA;AAGA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AAAA;AArda;;;;;;AD3Jb;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAC;AAED;AAEA;AAMA;AAAA;AAJA;AACA;AACA;AAKA;AACA;AACA;AAKA;AAQA;AACA;AACA;AACA;AACA;AACA;AAMA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAuBA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AAGA;AAAA;AACA;AAEA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAtQa;AA2Qb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADpSA;AAYA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AA/Ga;;;;;;ADcb;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAbA;AAmBA;AAGA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAbA;AAoBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAtBA;AAqCA;AACA;AAMA;AACA;AAGA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApDA;;;;;;AD/FA;AAEA;AACA;AACA;AAEa;AACA;AAKA;AACA;AACA;AACA;;;;;;;;;;;ADhBb;AAKA;AAAA;AAMA;AAAA;AAEA;;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAhDa;;;;;;ADJb;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAXA;AAaA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAWA;AAAA;AACA;AACA;;;AAAA;AAUA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AAhLa;;;;;;ADKb;AACA;AACA;AAFA;AAEC;;;;;;ADDD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAgBA;AAOA;AAMA;AAkBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAIA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAMA;AAKA;AAKA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AAQA;AAGA;AAGA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAKA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAIA;AAGA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAOA;AACA;AAQA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAYA;AACA;AAKA;AACA;AAIA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AACA;AAGA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAGA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AAGA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAQA;AACA;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAOA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AASA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAQA;AACA;AACA;AAEA;;;"} \ No newline at end of file +{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/Linkifier.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { Linkifier } from './Linkifier';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n this.linkifier = this.linkifier || null;;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n term.on('refresh', function (data) {\n term.queueLinkification(data.start, data.end)\n });\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n this.linkifier = new Linkifier(document, this.children);\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(document, this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n x = Math.ceil(x / self.charMeasure.width);\n y = Math.ceil(y / self.charMeasure.height);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Queues linkification for the specified rows.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\nTerminal.prototype.queueLinkification = function(start, end) {\n if (this.linkifier) {\n for (let i = start; i <= end; i++) {\n this.linkifier.linkifyRow(i);\n }\n }\n}\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Attaches a http(s) link handler, forcing web links to behave differently to\n * regular tags. This will trigger a refresh as links potentially need to be\n * reconstructed. Calling this with null will remove the handler.\n * @param {LinkHandler} handler The handler callback function.\n */\nTerminal.prototype.attachHypertextLinkHandler = function(handler) {\n if (!this.linkifier) {\n throw new Error('Cannot attach a hypertext link handler before Terminal.open is called');\n }\n this.linkifier.attachHypertextLinkHandler(handler);\n // Refresh to force links to refresh\n this.refresh(0, this.rows - 1);\n}\n\n/**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param {RegExp} regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param {LinkHandler} handler The callback when the link is called.\n * @param {LinkMatcherOptions} [options] Options for the link matcher.\n * @return {number} The ID of the new matcher, this can be used to deregister.\n */\nTerminal.prototype.registerLinkMatcher = function(regex, handler, options) {\n if (this.linkifier) {\n var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);\n this.refresh(0, this.rows - 1);\n return matcherId;\n }\n}\n\n/**\n * Deregisters a link matcher if it has been registered.\n * @param {number} matcherId The link matcher's ID (returned after register)\n */\nTerminal.prototype.deregisterLinkMatcher = function(matcherId) {\n if (this.linkifier) {\n if (this.linkifier.deregisterLinkMatcher(matcherId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _document: Document;\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(document: Document, parentElement: HTMLElement) {\n super();\n this._document = document;\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = this._document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n // Perform this async to ensure the CharMeasure is ready.\n setTimeout(() => this.syncScrollArea(), 0);\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { LinkMatcherOptions } from './Interfaces';\nimport { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types';\n\nconst INVALID_LINK_CLASS = 'xterm-invalid-link';\n\nconst protocolClause = '(https?:\\\\/\\\\/)';\nconst domainCharacterSet = '[\\\\da-z\\\\.-]+';\nconst negatedDomainCharacterSet = '[^\\\\da-z\\\\.-]+';\nconst domainBodyClause = '(' + domainCharacterSet + ')';\nconst tldClause = '([a-z\\\\.]{2,6})';\nconst ipClause = '((\\\\d{1,3}\\\\.){3}\\\\d{1,3})';\nconst localHostClause = '(localhost)';\nconst portClause = '(:\\\\d{1,5})';\nconst hostClause = '((' + domainBodyClause + '\\\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';\nconst pathClause = '(\\\\/[\\\\/\\\\w\\\\.\\\\-%]*)*';\nconst queryStringHashFragmentCharacterSet = '[0-9\\\\w\\\\[\\\\]\\\\(\\\\)\\\\/\\\\?\\\\!#@$%&\\'*+,:;\\\\=\\\\.\\\\-]*';\nconst queryStringClause = '(\\\\?' + queryStringHashFragmentCharacterSet + ')?';\nconst hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';\nconst negatedPathCharacterSet = '[^\\\\/\\\\w\\\\.\\\\-%]+';\nconst bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause;\nconst start = '(?:^|' + negatedDomainCharacterSet + ')(';\nconst end = ')($|' + negatedPathCharacterSet + ')';\nconst strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end);\n\n/**\n * The ID of the built in http(s) link matcher.\n */\nconst HYPERTEXT_LINK_MATCHER_ID = 0;\n\n/**\n * The Linkifier applies links to rows shortly after they have been refreshed.\n */\nexport class Linkifier {\n /**\n * The time to wait after a row is changed before it is linkified. This prevents\n * the costly operation of searching every row multiple times, pntentially a\n * huge aount of times.\n */\n protected static TIME_BEFORE_LINKIFY = 200;\n\n protected _linkMatchers: LinkMatcher[];\n\n private _document: Document;\n private _rows: HTMLElement[];\n private _rowTimeoutIds: number[];\n private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;\n\n constructor(document: Document, rows: HTMLElement[]) {\n this._document = document;\n this._rows = rows;\n this._rowTimeoutIds = [];\n this._linkMatchers = [];\n this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });\n }\n\n /**\n * Queues a row for linkification.\n * @param {number} rowIndex The index of the row to linkify.\n */\n public linkifyRow(rowIndex: number): void {\n const timeoutId = this._rowTimeoutIds[rowIndex];\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), Linkifier.TIME_BEFORE_LINKIFY);\n }\n\n /**\n * Attaches a handler for hypertext links, overriding default behavior\n * for standard http(s) links.\n * @param {LinkHandler} handler The handler to use, this can be cleared with\n * null.\n */\n public attachHypertextLinkHandler(handler: LinkMatcherHandler): void {\n this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler;\n }\n\n /**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param {RegExp} regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param {LinkHandler} handler The callback when the link is called.\n * @param {LinkMatcherOptions} [options] Options for the link matcher.\n * @return {number} The ID of the new matcher, this can be used to deregister.\n */\n public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: LinkMatcherOptions = {}): number {\n if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) {\n throw new Error('handler must be defined');\n }\n const matcher: LinkMatcher = {\n id: this._nextLinkMatcherId++,\n regex,\n handler,\n matchIndex: options.matchIndex,\n validationCallback: options.validationCallback,\n priority: options.priority || 0\n };\n this._addLinkMatcherToList(matcher);\n return matcher.id;\n }\n\n /**\n * Inserts a link matcher to the list in the correct position based on the\n * priority of each link matcher. New link matchers of equal priority are\n * considered after older link matchers.\n * @param matcher The link matcher to be added.\n */\n private _addLinkMatcherToList(matcher: LinkMatcher): void {\n if (this._linkMatchers.length === 0) {\n this._linkMatchers.push(matcher);\n return;\n }\n\n for (let i = this._linkMatchers.length - 1; i >= 0; i--) {\n if (matcher.priority <= this._linkMatchers[i].priority) {\n this._linkMatchers.splice(i + 1, 0, matcher);\n return;\n }\n }\n\n this._linkMatchers.splice(0, 0, matcher);\n }\n\n /**\n * Deregisters a link matcher if it has been registered.\n * @param {number} matcherId The link matcher's ID (returned after register)\n * @return {boolean} Whether a link matcher was found and deregistered.\n */\n public deregisterLinkMatcher(matcherId: number): boolean {\n // ID 0 is the hypertext link matcher which cannot be deregistered\n for (let i = 1; i < this._linkMatchers.length; i++) {\n if (this._linkMatchers[i].id === matcherId) {\n this._linkMatchers.splice(i, 1);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Linkifies a row.\n * @param {number} rowIndex The index of the row to linkify.\n */\n private _linkifyRow(rowIndex: number): void {\n const row = this._rows[rowIndex];\n if (!row) {\n return;\n }\n const text = row.textContent;\n for (let i = 0; i < this._linkMatchers.length; i++) {\n const matcher = this._linkMatchers[i];\n const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex);\n if (uri) {\n const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID);\n // Fire validation callback\n if (linkElement && matcher.validationCallback) {\n matcher.validationCallback(uri, isValid => {\n if (!isValid) {\n linkElement.classList.add(INVALID_LINK_CLASS);\n }\n });\n }\n // Only allow a single LinkMatcher to trigger on any given row.\n return;\n }\n }\n }\n\n /**\n * Linkifies a row given a specific handler.\n * @param {number} rowIndex The index of the row to linkify.\n * @param {string} uri The uri that has been found.\n * @param {handler} handler The handler to trigger when the link is triggered.\n * @return The link element if it was added, otherwise undefined.\n */\n private _doLinkifyRow(rowIndex: number, uri: string, handler: LinkMatcherHandler, isHttpLinkMatcher: boolean): HTMLElement {\n // Iterate over nodes as we want to consider text nodes\n const nodes = this._rows[rowIndex].childNodes;\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const searchIndex = node.textContent.indexOf(uri);\n if (searchIndex >= 0) {\n const linkElement = this._createAnchorElement(uri, handler, isHttpLinkMatcher);\n if (node.textContent.length === uri.length) {\n // Matches entire string\n\n if (node.nodeType === 3 /*Node.TEXT_NODE*/) {\n this._replaceNode(node, linkElement);\n } else {\n const element = (node);\n if (element.nodeName === 'A') {\n // This row has already been linkified\n return;\n }\n element.innerHTML = '';\n element.appendChild(linkElement);\n }\n } else {\n // Matches part of string\n this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex);\n }\n return linkElement;\n }\n }\n }\n\n /**\n * Finds a link match in a piece of text.\n * @param {string} text The text to search.\n * @param {number} matchIndex The regex match index of the link.\n * @return {string} The matching URI or null if not found.\n */\n private _findLinkMatch(text: string, regex: RegExp, matchIndex?: number): string {\n const match = text.match(regex);\n if (!match || match.length === 0) {\n return null;\n }\n return match[typeof matchIndex !== 'number' ? 0 : matchIndex];\n }\n\n /**\n * Creates a link anchor element.\n * @param {string} uri The uri of the link.\n * @return {HTMLAnchorElement} The link.\n */\n private _createAnchorElement(uri: string, handler: LinkMatcherHandler, isHypertextLinkHandler: boolean): HTMLAnchorElement {\n const element = this._document.createElement('a');\n element.textContent = uri;\n if (isHypertextLinkHandler) {\n element.href = uri;\n // Force link on another tab so work is not lost\n element.target = '_blank';\n element.addEventListener('click', (event: MouseEvent) => {\n if (handler) {\n return handler(event, uri);\n }\n });\n } else {\n element.addEventListener('click', (event: MouseEvent) => {\n // Don't execute the handler if the link is flagged as invalid\n if (element.classList.contains(INVALID_LINK_CLASS)) {\n return;\n }\n return handler(event, uri);\n });\n }\n return element;\n }\n\n /**\n * Replace a node with 1 or more other nodes.\n * @param {Node} oldNode The node to replace.\n * @param {Node[]} newNodes The new nodes to insert in order.\n */\n private _replaceNode(oldNode: Node, ...newNodes: Node[]): void {\n const parent = oldNode.parentNode;\n for (let i = 0; i < newNodes.length; i++) {\n parent.insertBefore(newNodes[i], oldNode);\n }\n parent.removeChild(oldNode);\n }\n\n /**\n * Replace a substring within a node with a new node.\n * @param {Node} targetNode The target node; either a text node or a \n * containing a single text node.\n * @param {Node} newNode The new node to insert.\n * @param {string} substring The substring to replace.\n * @param {number} substringIndex The index of the substring within the string.\n */\n private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): void {\n let node = targetNode;\n if (node.nodeType !== 3/*Node.TEXT_NODE*/) {\n node = node.childNodes[0];\n }\n\n // The targetNode will be either a text node or a . The text node\n // (targetNode or its only-child) needs to be replaced with newNode plus new\n // text nodes potentially on either side.\n if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) {\n throw new Error('targetNode must be a text node or only contain a single text node');\n }\n\n const fullText = node.textContent;\n\n if (substringIndex === 0) {\n // Replace with \n const rightText = fullText.substring(substring.length);\n const rightTextNode = this._document.createTextNode(rightText);\n this._replaceNode(node, newNode, rightTextNode);\n } else if (substringIndex === targetNode.textContent.length - substring.length) {\n // Replace with \n const leftText = fullText.substring(0, substringIndex);\n const leftTextNode = this._document.createTextNode(leftText);\n this._replaceNode(node, leftTextNode, newNode);\n } else {\n // Replace with \n const leftText = fullText.substring(0, substringIndex);\n const leftTextNode = this._document.createTextNode(leftText);\n const rightText = fullText.substring(substringIndex + substring.length);\n const rightTextNode = this._document.createTextNode(rightText);\n this._replaceNode(node, leftTextNode, newNode, rightTextNode);\n }\n }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * @license MIT\n */\n\n/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"AeAA;;ADSa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AD3OA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AACA;AAAA;AApNa;;;;;;ADRb;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAAC;;;;;;ADtEA;AAED;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA9Da;;;;;;ADJb;AACA;AASA;AAEA;AAAA;AAAA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAkEA;AAEA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAj7Ca;AAm7Cb;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADliDA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAKA;AAeA;AAFA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;;AAhBA;AAAA;;;AAgBA;AACA;AASA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA5QmB;AANN;;;;;;ADhCb;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAKA;AACA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAIA;AACA;AAGA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AAAA;AArda;;;;;;AD3Jb;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAC;AAED;AAEA;AAMA;AAAA;AAJA;AACA;AACA;AAKA;AACA;AACA;AAKA;AAQA;AACA;AACA;AACA;AACA;AACA;AAMA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAuBA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AAGA;AAAA;AACA;AAEA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAtQa;AA2Qb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADpSA;AAYA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AA/Ga;;;;;;ADcb;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAbA;AAmBA;AAGA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAbA;AAoBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAtBA;AAqCA;AACA;AAMA;AACA;AAGA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApDA;;;;;;AD/FA;AAEA;AACA;AACA;AAEa;AACA;AAKA;AACA;AACA;AACA;;;;;;;;;;;ADhBb;AAKA;AAAA;AAOA;AAAA;AAEA;AACA;;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAnDa;;;;;;ADJb;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAXA;AAaA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAWA;AAAA;AACA;AACA;;;AAAA;AAUA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AAhLa;;;;;;ADKb;AACA;AACA;AAFA;AAEC;;;;;;ADDD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAgBA;AAOA;AAMA;AAkBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAIA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAMA;AAKA;AAKA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AAQA;AAGA;AAGA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAKA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAIA;AAGA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAOA;AACA;AAQA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAYA;AACA;AAKA;AACA;AAIA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AACA;AAGA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAGA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AAGA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAQA;AACA;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAOA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AASA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAQA;AACA;AACA;AAEA;;;"} \ No newline at end of file diff --git a/package.json b/package.json index 23958043..27579a0d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "2.3.2", + "version": "2.4.0", "ignore": [ "demo", "test", From 0bbd8f0a163cd9dddd1286fd218c0d6e654bd668 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 7 Mar 2017 14:01:29 -0800 Subject: [PATCH 175/211] Implement CSI 3 J - Erase saved lines Fixes #587 --- src/InputHandler.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 37f41f34..a7023083 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -385,7 +385,13 @@ export class InputHandler implements IInputHandler { while (j--) this._terminal.eraseLine(j); break; case 3: - ; // no saved lines + // Clear scrollback (everything not in viewport) + const scrollBackSize = this._terminal.lines.length - this._terminal.rows; + if (scrollBackSize > 0) { + this._terminal.lines.trimStart(scrollBackSize); + this._terminal.ybase = Math.max(this._terminal.ybase - scrollBackSize, 0); + this._terminal.ydisp = Math.max(this._terminal.ydisp - scrollBackSize, 0); + } break; } } From 31a0996b2f6084621bb18dbd836dbadad91433ea Mon Sep 17 00:00:00 2001 From: yutaka Date: Wed, 8 Mar 2017 00:27:22 +0000 Subject: [PATCH 176/211] Revert "Set charMeasure.height values to each row height" This reverts commit 43cb4f471fb69ec1bd7d5f0bf99fe867c8056d56. --- src/xterm.js | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 8385b601..a08e9dd1 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -562,7 +562,6 @@ Terminal.bindKeys = function(term) { Terminal.prototype.insertRow = function (row) { if (typeof row != 'object') { row = document.createElement('div'); - row.style.height = this.charMeasure.height + 'px'; } this.rowContainer.appendChild(row); @@ -643,18 +642,17 @@ Terminal.prototype.open = function(parent) { this.charSizeStyleElement = document.createElement('style'); this.helperContainer.appendChild(this.charSizeStyleElement); - this.charMeasure = new CharMeasure(document, this.helperContainer); - this.charMeasure.on('charsizechanged', function () { - self.updateCharSizeCSS(); - self.updateRowHeight(); - }); - this.charMeasure.measure(); - for (; i < this.rows; i++) { this.insertRow(); } this.parent.appendChild(this.element); + this.charMeasure = new CharMeasure(document, this.helperContainer); + this.charMeasure.on('charsizechanged', function () { + self.updateCharSizeCSS(); + }); + this.charMeasure.measure(); + this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); this.renderer = new Renderer(this); @@ -716,15 +714,6 @@ Terminal.prototype.updateCharSizeCSS = function() { this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}'; } -/** - * Updates the height for each rows - */ -Terminal.prototype.updateRowHeight = function() { - for (var i = 0; i < this.children.length; ++i) { - this.children[i].style.height = this.charMeasure.height + 'px'; - } -} - /** * XTerm mouse events * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking From f0d5b4012134a617408c38eb98382c1ef36ebe17 Mon Sep 17 00:00:00 2001 From: yutaka Date: Wed, 8 Mar 2017 01:03:18 +0000 Subject: [PATCH 177/211] Detect bold font was broken correctly. --- src/Renderer.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Renderer.ts b/src/Renderer.ts index 9b6234ca..e1ebbe8f 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -34,7 +34,7 @@ export class Renderer { // Figure out whether boldness affects // the character width of monospace fonts. if (brokenBold === null) { - brokenBold = checkBoldBroken((this._terminal).document); + brokenBold = checkBoldBroken((this._terminal).element); } // TODO: Pull more DOM interactions into Renderer.constructor, element for @@ -291,14 +291,14 @@ export class Renderer { // if bold is broken, we can't // use it in the terminal. -function checkBoldBroken(document) { - const body = document.getElementsByTagName('body')[0]; +function checkBoldBroken(terminal) { + const document = terminal.ownerDocument; const el = document.createElement('span'); el.innerHTML = 'hello world'; - body.appendChild(el); + terminal.appendChild(el); const w1 = el.scrollWidth; el.style.fontWeight = 'bold'; const w2 = el.scrollWidth; - body.removeChild(el); + terminal.removeChild(el); return w1 !== w2; } From 2ec756fd6bfadf2689d1c243960efaa01a7f93a4 Mon Sep 17 00:00:00 2001 From: yutaka Date: Wed, 8 Mar 2017 00:44:57 +0000 Subject: [PATCH 178/211] Use offsetWidth instead of scrollWidth scrollWidth does not work on Chrome with `display: inline` element. --- src/Renderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Renderer.ts b/src/Renderer.ts index e1ebbe8f..a839e7d9 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -296,9 +296,9 @@ function checkBoldBroken(terminal) { const el = document.createElement('span'); el.innerHTML = 'hello world'; terminal.appendChild(el); - const w1 = el.scrollWidth; + const w1 = el.offsetWidth; el.style.fontWeight = 'bold'; - const w2 = el.scrollWidth; + const w2 = el.offsetWidth; terminal.removeChild(el); return w1 !== w2; } From 4b2ae6a79fb0f899e895093ef440ac9977210d8f Mon Sep 17 00:00:00 2001 From: yutaka Date: Wed, 8 Mar 2017 05:12:25 +0000 Subject: [PATCH 179/211] Use rendered height for detect broken bold font. --- src/Renderer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Renderer.ts b/src/Renderer.ts index a839e7d9..4131abc4 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -297,8 +297,10 @@ function checkBoldBroken(terminal) { el.innerHTML = 'hello world'; terminal.appendChild(el); const w1 = el.offsetWidth; + const h1 = el.offsetHeight; el.style.fontWeight = 'bold'; const w2 = el.offsetWidth; + const h2 = el.offsetHeight; terminal.removeChild(el); - return w1 !== w2; + return w1 !== w2 || h1 !== h2; } From d8f8b060cb04dd39d4b33cce477df048e3f55b53 Mon Sep 17 00:00:00 2001 From: Nicolas Ramz Date: Thu, 9 Mar 2017 00:47:29 +0100 Subject: [PATCH 180/211] FIXED: typo `
` wasn't used, instead, a new one was created and used since getElementById('#terminal') returned null. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12ec9ef2..84b116df 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t
From b66776a047bf45a2f6ecb57cd70636f1ce849176 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Mar 2017 10:23:59 -0800 Subject: [PATCH 181/211] Include element in validationCallback Fixes #591 --- src/Linkifier.test.ts | 4 ++-- src/Linkifier.ts | 2 +- src/Types.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 012b1b68..97750c94 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -53,7 +53,7 @@ describe('Linkifier', () => { it('should enable link if true', done => { addRow('test'); linkifier.registerLinkMatcher(/test/, () => done(), { - validationCallback: (url, cb) => { + validationCallback: (url, element, cb) => { cb(true); assert.equal((rows[0].firstChild).tagName, 'A'); setTimeout(() => clickElement(rows[0].firstChild), 0); @@ -65,7 +65,7 @@ describe('Linkifier', () => { it('should disable link if false', done => { addRow('test'); linkifier.registerLinkMatcher(/test/, () => assert.fail(), { - validationCallback: (url, cb) => { + validationCallback: (url, element, cb) => { cb(false); assert.equal((rows[0].firstChild).tagName, 'A'); setTimeout(() => clickElement(rows[0].firstChild), 0); diff --git a/src/Linkifier.ts b/src/Linkifier.ts index a34edbc2..77cd16c1 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -160,7 +160,7 @@ export class Linkifier { const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID); // Fire validation callback if (linkElement && matcher.validationCallback) { - matcher.validationCallback(uri, isValid => { + matcher.validationCallback(uri, linkElement, isValid => { if (!isValid) { linkElement.classList.add(INVALID_LINK_CLASS); } diff --git a/src/Types.ts b/src/Types.ts index 9e8cd762..896b729a 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -11,4 +11,4 @@ export type LinkMatcher = { priority?: number }; export type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void; -export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; +export type LinkMatcherValidationCallback = (uri: string, element: HTMLElement, callback: (isValid: boolean) => void) => void; From 11f62bab342475b178abded7c1a1dbf2af96e431 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Mar 2017 10:38:21 -0800 Subject: [PATCH 182/211] Expose setHypertextValidationCallback --- src/Linkifier.ts | 11 ++++++++++- src/xterm.js | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 77cd16c1..e7fbcb50 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -75,10 +75,19 @@ export class Linkifier { * @param {LinkHandler} handler The handler to use, this can be cleared with * null. */ - public attachHypertextLinkHandler(handler: LinkMatcherHandler): void { + public setHypertextLinkHandler(handler: LinkMatcherHandler): void { this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; } + /** + * Attaches a validation callback for hypertext links. + * @param {LinkMatcherValidationCallback} callback The callback to use, this + * can be cleared with null. + */ + public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback; + } + /** * Registers a link matcher, allowing custom link patterns to be matched and * handled. diff --git a/src/xterm.js b/src/xterm.js index 37c00ed8..86f648b6 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1286,7 +1286,7 @@ Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) { * reconstructed. Calling this with null will remove the handler. * @param {LinkHandler} handler The handler callback function. */ -Terminal.prototype.attachHypertextLinkHandler = function(handler) { +Terminal.prototype.setHypertextLinkHandler = function(handler) { if (!this.linkifier) { throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); } @@ -1295,6 +1295,21 @@ Terminal.prototype.attachHypertextLinkHandler = function(handler) { this.refresh(0, this.rows - 1); } +/** + * Attaches a validation callback for hypertext links. This is useful to use + * validation logic or to do something with the link's element and url. + * @param {LinkMatcherValidationCallback} callback The callback to use, this can + * be cleared with null. + */ +Terminal.prototype.setHypertextValidationCallback = function(handler) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called'); + } + this.linkifier.setHypertextValidationCallback(handler); + // Refresh to force links to refresh + this.refresh(0, this.rows - 1); +} + /** * Registers a link matcher, allowing custom link patterns to be matched and * handled. From bef7137c925f4e113cd35d26179aeea9b4b2f5c3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Mar 2017 10:47:09 -0800 Subject: [PATCH 183/211] Fix bug --- src/xterm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.js b/src/xterm.js index 86f648b6..f139bbc9 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1290,7 +1290,7 @@ Terminal.prototype.setHypertextLinkHandler = function(handler) { if (!this.linkifier) { throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); } - this.linkifier.attachHypertextLinkHandler(handler); + this.linkifier.setHypertextLinkHandler(handler); // Refresh to force links to refresh this.refresh(0, this.rows - 1); } From 3c3a646d423caad334b2086e76d2ccdf34f6d4f7 Mon Sep 17 00:00:00 2001 From: Michael Irwin Date: Tue, 14 Mar 2017 17:02:53 -0400 Subject: [PATCH 184/211] Fixed characterHeight calculation, which could cause overflowing The previous calculation was simply using the height of the letter W, but wasn't taking into account that each row has a lineHeight, which might be greater. If the lineHeight is .4px off, after many rows, it will cause the proposedGeometry to have an extra row, potentially causing hidden rows (based on layout). --- src/addons/fit/fit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/fit/fit.js b/src/addons/fit/fit.js index 11fc6eb7..390cc0e9 100644 --- a/src/addons/fit/fit.js +++ b/src/addons/fit/fit.js @@ -56,7 +56,7 @@ subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace characterWidth = subjectRow.getBoundingClientRect().width; subjectRow.style.display = ''; // Revert style before calculating height, since they differ. - characterHeight = parseInt(subjectRow.offsetHeight); + characterHeight = parseFloat(term.rowContainer.style.lineHeight); subjectRow.innerHTML = contentBuffer; rows = parseInt(availableHeight / characterHeight); From 8cf76cc6e93d8a109a59d7315405dca3150e134e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 14 Mar 2017 15:15:36 -0700 Subject: [PATCH 185/211] Polish development and contribution section --- README.md | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/README.md b/README.md index 84b116df..9c22a777 100644 --- a/README.md +++ b/README.md @@ -121,27 +121,7 @@ The existing releases are available at this GitHub repo's [Releases](https://git Xterm.js is maintained by [SourceLair](https://www.sourcelair.com/) and a few external contributors, but we would love to receive contributions from everyone! -To contribute either code, documentation or issues to xterm.js please read the [Contributing document](CONTRIBUTING.md) before. - -The development of xterm.js does not require any special tool. All you need is an editor that supports JavaScript and a browser (if you would like to run the demo you will need Node.js to get all features). - -It is recommended though to use a development tool that uses xterm.js internally, to develop for xterm.js. [Eating our own dogfood](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) has been proved extremely beneficial for this project. Known tools that use xterm.js internally are: - -#### [SourceLair](https://www.sourcelair.com) - -Visit https://lair.io/sourcelair/xterm and follow the instructions. All development will happen in your browser. - -#### [Visual Studio Code](http://code.visualstudio.com/) - -[Download Visual Studio Code](http://code.visualstudio.com/Download), clone xterm.js and you are all set. - -#### [Eclipse Che](http://www.eclipse.org/che) - -You can start Eclipse Che with `docker run eclipse/che start`. - -#### [Codenvy](http://www.codenvy.io) - -You can create a trial account or install an enterprise version with `docker run codenvy/cli start`. +To contribute either code, documentation or issues to xterm.js please read the [Contributing document](CONTRIBUTING.md) beforehand. The development of xterm.js does not require any special tool. All you need is an editor that supports JavaScript/TypeScript and a browser. You will need Node.js installed locally to get all the features working in the demo. ## License Agreement From 0cb8ecc6f72638aa65f6c04fc5fd5a241f2f482c Mon Sep 17 00:00:00 2001 From: Michael Irwin Date: Wed, 15 Mar 2017 08:28:44 -0400 Subject: [PATCH 186/211] Use boundingClientRect instead of style to get actual height PR #598 --- src/addons/fit/fit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/fit/fit.js b/src/addons/fit/fit.js index 390cc0e9..46b79e9b 100644 --- a/src/addons/fit/fit.js +++ b/src/addons/fit/fit.js @@ -56,7 +56,7 @@ subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace characterWidth = subjectRow.getBoundingClientRect().width; subjectRow.style.display = ''; // Revert style before calculating height, since they differ. - characterHeight = parseFloat(term.rowContainer.style.lineHeight); + characterHeight = subjectRow.getBoundingClientRect().height; subjectRow.innerHTML = contentBuffer; rows = parseInt(availableHeight / characterHeight); From 9055bace966d7ef6862d1596a369ee306f00dbaf Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 15 Mar 2017 18:28:17 +0200 Subject: [PATCH 187/211] Fix cursor style on blurred terminals --- src/xterm.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.css b/src/xterm.css index b7f120f9..aac95444 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -86,7 +86,7 @@ text-decoration: none; } -.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { +.terminal.focus:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { background-color: #fff; color: #000; } From 5225a6e27a54314d28564296bf60a8e59d969037 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 15 Mar 2017 18:36:06 +0200 Subject: [PATCH 188/211] Rebuild xterm.js even when CSS changes Otherwise you had to run `npm build` manually every time you changed a CSS file to see the updated result in the demo. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27579a0d..c1d07e3c 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "scripts": { "prestart": "npm run build", "start": "node demo/app", - "dev": "nodemon -e js,ts --watch src --watch demo --exec npm start", + "dev": "nodemon -e js,ts,css --watch src --watch demo --exec npm start", "lint": "tslint src/*.ts src/**/*.ts", "test": "gulp test", "build:docs": "jsdoc -c jsdoc.json", From b68180b97bde51b2cb85923921eee2e35e0c79ed Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 15 Mar 2017 13:54:36 -0700 Subject: [PATCH 189/211] Allow ~ char in linkify path and query fragments --- src/Linkifier.test.ts | 14 ++++++++++++++ src/Linkifier.ts | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 012b1b68..ca393c21 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -49,6 +49,20 @@ describe('Linkifier', () => { element.dispatchEvent(event); } + function assertLinkifiesEntireRow(uri: string, done: MochaDone) { + addRow(uri); + linkifier.linkifyRow(0); + setTimeout(() => { + assert.equal((rows[0].firstChild).tagName, 'A'); + assert.equal((rows[0].firstChild).textContent, uri); + done(); + }, 0); + } + + describe('http links', () => { + it('should allow ~ character in URI path', done => assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done)); + }); + describe('validationCallback', () => { it('should enable link if true', done => { addRow('test'); diff --git a/src/Linkifier.ts b/src/Linkifier.ts index a34edbc2..df7b08a3 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -16,8 +16,8 @@ const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; -const pathClause = '(\\/[\\/\\w\\.\\-%]*)*'; -const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;\\=\\.\\-]*'; +const pathClause = '(\\/[\\/\\w\\.\\-%~]*)*'; +const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; const negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; From 22cc8079dc17437490189c08fc3bd895e3815975 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Thu, 16 Mar 2017 10:53:56 +0200 Subject: [PATCH 190/211] Add xterm.js logo --- README.md | 2 +- logo.png | Bin 0 -> 8446 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 logo.png diff --git a/README.md b/README.md index 9c22a777..af98ed58 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# xterm.js +# [![xterm.js logo](logo.png)](https://xtermjs.org) [![xterm.js build status](https://api.travis-ci.org/sourcelair/xterm.js.svg)](https://travis-ci.org/sourcelair/xterm.js) [![Coverage Status](https://coveralls.io/repos/github/sourcelair/xterm.js/badge.svg)](https://coveralls.io/github/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c16ac7260d4fca251eb2a09b1d1b0af77a39a3f4 GIT binary patch literal 8446 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 Date: Thu, 16 Mar 2017 12:07:25 -0700 Subject: [PATCH 191/211] Ensure terminal links are not draggable --- src/Linkifier.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index a34edbc2..e0e2e7c4 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -232,6 +232,7 @@ export class Linkifier { private _createAnchorElement(uri: string, handler: LinkMatcherHandler, isHypertextLinkHandler: boolean): HTMLAnchorElement { const element = this._document.createElement('a'); element.textContent = uri; + element.draggable = false; if (isHypertextLinkHandler) { element.href = uri; // Force link on another tab so work is not lost From 365f9b4c1bb0a6175d005b1adc8853d4cf513d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Sat, 18 Mar 2017 18:05:05 -0500 Subject: [PATCH 192/211] Added Spyder IDE as a xterm case-use application --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index af98ed58..28d1ac47 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams. - [**CoderPad**](https://coderpad.io): Online interviewing platform for programmers. Run code in many programming languages, with results displayed by `xterm.js`. - [**WebSSH2**](https://github.com/billchurch/WebSSH2): A web based SSH2 client using `xterm.js`, socket.io, and ssh2. +- [**Spyder Terminal**](https://github.com/spyder-ide/spyder-terminal): A full fledged system terminal embedded on Spyder IDE. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From cb77b9dc1a07ae4549d09da4c81307c1fd1201cb Mon Sep 17 00:00:00 2001 From: Lucian Buzzo Date: Sun, 19 Mar 2017 08:26:37 +0000 Subject: [PATCH 193/211] Prevent line data from being discarded on resize. --- src/xterm.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 37c00ed8..830b8f84 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1805,14 +1805,8 @@ Terminal.prototype.resize = function(x, y) { this.lines.get(i).push(ch); } } - } else { // (j > x) - i = this.lines.length; - while (i--) { - while (this.lines.get(i).length > x) { - this.lines.get(i).pop(); - } - } } + this.cols = x; this.setupStops(this.cols); From b0624cadb7ca5756c260a2857833ffd831cbfb2f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 24 Mar 2017 11:04:04 -0700 Subject: [PATCH 194/211] Allow links to be registered before terminal is attached to DOM Fixes #618 --- src/Linkifier.test.ts | 154 +++++++++++++++++++++++------------------- src/Linkifier.ts | 19 +++++- src/xterm.js | 4 +- 3 files changed, 103 insertions(+), 74 deletions(-) diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index ca393c21..36f825ba 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -8,9 +8,9 @@ import { Linkifier } from './Linkifier'; import { LinkMatcher } from './Types'; class TestLinkifier extends Linkifier { - constructor(document: Document, rows: HTMLElement[]) { + constructor() { Linkifier.TIME_BEFORE_LINKIFY = 0; - super(document, rows); + super(); } public get linkMatchers(): LinkMatcher[] { return this._linkMatchers; } @@ -25,89 +25,105 @@ describe('Linkifier', () => { let linkifier: TestLinkifier; beforeEach(done => { - rows = []; jsdom.env('', (err, w) => { window = w; document = window.document; - linkifier = new TestLinkifier(document, rows); - container = document.createElement('div'); - document.body.appendChild(container); + linkifier = new TestLinkifier(); done(); }); }); - function addRow(text: string) { - const element = document.createElement('div'); - element.textContent = text; - container.appendChild(element); - rows.push(element); - } - - function clickElement(element: Node) { - const event = document.createEvent('MouseEvent'); - event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); - element.dispatchEvent(event); - } - - function assertLinkifiesEntireRow(uri: string, done: MochaDone) { - addRow(uri); - linkifier.linkifyRow(0); - setTimeout(() => { - assert.equal((rows[0].firstChild).tagName, 'A'); - assert.equal((rows[0].firstChild).textContent, uri); + describe('before attachToDom', () => { + it('should allow link matcher registration', done => { + assert.doesNotThrow(() => { + const linkMatcherId = linkifier.registerLinkMatcher(/foo/, () => {}); + assert.isTrue(linkifier.deregisterLinkMatcher(linkMatcherId)); done(); - }, 0); - } - - describe('http links', () => { - it('should allow ~ character in URI path', done => assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done)); - }); - - describe('validationCallback', () => { - it('should enable link if true', done => { - addRow('test'); - linkifier.registerLinkMatcher(/test/, () => done(), { - validationCallback: (url, cb) => { - cb(true); - assert.equal((rows[0].firstChild).tagName, 'A'); - setTimeout(() => clickElement(rows[0].firstChild), 0); - } }); - linkifier.linkifyRow(0); - }); - - it('should disable link if false', done => { - addRow('test'); - linkifier.registerLinkMatcher(/test/, () => assert.fail(), { - validationCallback: (url, cb) => { - cb(false); - assert.equal((rows[0].firstChild).tagName, 'A'); - setTimeout(() => clickElement(rows[0].firstChild), 0); - } - }); - linkifier.linkifyRow(0); - // Allow time for the click to be performed - setTimeout(() => done(), 10); }); }); - describe('priority', () => { - it('should order the list from highest priority to lowest #1', () => { - const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 1 }); - const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: -1 }); - assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [aId, 0, bId]); + describe('after attachToDom', () => { + beforeEach(() => { + rows = []; + linkifier.attachToDom(document, rows); + container = document.createElement('div'); + document.body.appendChild(container); }); - it('should order the list from highest priority to lowest #2', () => { - const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: -1 }); - const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 1 }); - assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [bId, 0, aId]); + function addRow(text: string) { + const element = document.createElement('div'); + element.textContent = text; + container.appendChild(element); + rows.push(element); + } + + function clickElement(element: Node) { + const event = document.createEvent('MouseEvent'); + event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + element.dispatchEvent(event); + } + + function assertLinkifiesEntireRow(uri: string, done: MochaDone) { + addRow(uri); + linkifier.linkifyRow(0); + setTimeout(() => { + assert.equal((rows[0].firstChild).tagName, 'A'); + assert.equal((rows[0].firstChild).textContent, uri); + done(); + }, 0); + } + + describe('http links', () => { + it('should allow ~ character in URI path', done => assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done)); }); - it('should order items of equal priority in the order they are added', () => { - const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 0 }); - const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 0 }); - assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [0, aId, bId]); + describe('validationCallback', () => { + it('should enable link if true', done => { + addRow('test'); + linkifier.registerLinkMatcher(/test/, () => done(), { + validationCallback: (url, cb) => { + cb(true); + assert.equal((rows[0].firstChild).tagName, 'A'); + setTimeout(() => clickElement(rows[0].firstChild), 0); + } + }); + linkifier.linkifyRow(0); + }); + + it('should disable link if false', done => { + addRow('test'); + linkifier.registerLinkMatcher(/test/, () => assert.fail(), { + validationCallback: (url, cb) => { + cb(false); + assert.equal((rows[0].firstChild).tagName, 'A'); + setTimeout(() => clickElement(rows[0].firstChild), 0); + } + }); + linkifier.linkifyRow(0); + // Allow time for the click to be performed + setTimeout(() => done(), 10); + }); + }); + + describe('priority', () => { + it('should order the list from highest priority to lowest #1', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 1 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: -1 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [aId, 0, bId]); + }); + + it('should order the list from highest priority to lowest #2', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: -1 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 1 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [bId, 0, aId]); + }); + + it('should order items of equal priority in the order they are added', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 0 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 0 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [0, aId, bId]); + }); }); }); }); diff --git a/src/Linkifier.ts b/src/Linkifier.ts index d9a16940..c263496a 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -49,19 +49,32 @@ export class Linkifier { private _rowTimeoutIds: number[]; private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; - constructor(document: Document, rows: HTMLElement[]) { - this._document = document; - this._rows = rows; + constructor() { this._rowTimeoutIds = []; this._linkMatchers = []; this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); } + /** + * Attaches the linkifier to the DOM, enabling linkification. + * @param document The document object. + * @param rows The array of rows to apply links to. + */ + public attachToDom(document: Document, rows: HTMLElement[]) { + this._document = document; + this._rows = rows; + } + /** * Queues a row for linkification. * @param {number} rowIndex The index of the row to linkify. */ public linkifyRow(rowIndex: number): void { + // Don't attempt linkify if not yet attached to DOM + if (!this._document) { + return; + } + const timeoutId = this._rowTimeoutIds[rowIndex]; if (timeoutId) { clearTimeout(timeoutId); diff --git a/src/xterm.js b/src/xterm.js index 830b8f84..13fca0bb 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -211,7 +211,7 @@ function Terminal(options) { this.parser = new Parser(this.inputHandler, this); // Reuse renderer if the Terminal is being recreated via a Terminal.reset call. this.renderer = this.renderer || null; - this.linkifier = this.linkifier || null;; + this.linkifier = this.linkifier || new Linkifier(); // user input states this.writeBuffer = []; @@ -612,7 +612,7 @@ Terminal.prototype.open = function(parent) { this.rowContainer.classList.add('xterm-rows'); this.element.appendChild(this.rowContainer); this.children = []; - this.linkifier = new Linkifier(document, this.children); + this.linkifier.attachToDom(document, this.children); // Create the container that will hold helpers like the textarea for // capturing DOM Events. Then produce the helpers. From 44cfb2dc87b02948e7e3d565796fd9ccc91b8739 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 30 Mar 2017 14:26:56 +0300 Subject: [PATCH 195/211] Added Cloud Commander to real world uses --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 28d1ac47..d0de1569 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**CoderPad**](https://coderpad.io): Online interviewing platform for programmers. Run code in many programming languages, with results displayed by `xterm.js`. - [**WebSSH2**](https://github.com/billchurch/WebSSH2): A web based SSH2 client using `xterm.js`, socket.io, and ssh2. - [**Spyder Terminal**](https://github.com/spyder-ide/spyder-terminal): A full fledged system terminal embedded on Spyder IDE. +- [**Cloud Commander**](https://cloudcmd.io "Cloud Commander"): Orthodox web file manager with console and editor. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From 08fd050c3f9bfd3eafe14ebfb41e1426bfaff973 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 31 Mar 2017 01:48:35 -0700 Subject: [PATCH 196/211] Support multiple link matches in a single row Fixes #612 --- src/Linkifier.ts | 98 +++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index d9a16940..85d1bd5e 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -155,16 +155,17 @@ export class Linkifier { const text = row.textContent; for (let i = 0; i < this._linkMatchers.length; i++) { const matcher = this._linkMatchers[i]; - const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex); - if (uri) { - const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID); + const linkElements = this._doLinkifyRow(row, matcher); + if (linkElements.length > 0) { // Fire validation callback - if (linkElement && matcher.validationCallback) { - matcher.validationCallback(uri, isValid => { - if (!isValid) { - linkElement.classList.add(INVALID_LINK_CLASS); - } - }); + if (matcher.validationCallback) { + for (let j = 0; j < linkElements.length; j++) { + matcher.validationCallback(linkElements[j].textContent, isValid => { + if (!isValid) { + linkElements[j].classList.add(INVALID_LINK_CLASS); + } + }); + } } // Only allow a single LinkMatcher to trigger on any given row. return; @@ -174,22 +175,32 @@ export class Linkifier { /** * Linkifies a row given a specific handler. - * @param {number} rowIndex The index of the row to linkify. - * @param {string} uri The uri that has been found. - * @param {handler} handler The handler to trigger when the link is triggered. + * @param {HTMLElement} row The row to linkify. + * @param {LinkMatcher} matcher The link matcher for this line. * @return The link element if it was added, otherwise undefined. */ - private _doLinkifyRow(rowIndex: number, uri: string, handler: LinkMatcherHandler, isHttpLinkMatcher: boolean): HTMLElement { + private _doLinkifyRow(row: HTMLElement, matcher: LinkMatcher): HTMLElement[] { // Iterate over nodes as we want to consider text nodes - const nodes = this._rows[rowIndex].childNodes; + let result = []; + const isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID; + const nodes = row.childNodes; + + // Find the first match + let match = row.textContent.match(matcher.regex); + if (!match || match.length === 0) { + return result; + } + let uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + // Set the next searches start index + let rowStartIndex = match.index + uri.length; + for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; const searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { - const linkElement = this._createAnchorElement(uri, handler, isHttpLinkMatcher); + const linkElement = this._createAnchorElement(uri, matcher.handler, isHttpLinkMatcher); if (node.textContent.length === uri.length) { // Matches entire string - if (node.nodeType === 3 /*Node.TEXT_NODE*/) { this._replaceNode(node, linkElement); } else { @@ -203,25 +214,22 @@ export class Linkifier { } } else { // Matches part of string - this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); + const nodesAdded = this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); + // No need to consider the new nodes + i += nodesAdded - 1; } - return linkElement; + result.push(linkElement); + + // Find the next match + match = row.textContent.substring(rowStartIndex).match(matcher.regex); + if (!match || match.length === 0) { + return result; + } + uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + rowStartIndex += match.index + uri.length; } } - } - - /** - * Finds a link match in a piece of text. - * @param {string} text The text to search. - * @param {number} matchIndex The regex match index of the link. - * @return {string} The matching URI or null if not found. - */ - private _findLinkMatch(text: string, regex: RegExp, matchIndex?: number): string { - const match = text.match(regex); - if (!match || match.length === 0) { - return null; - } - return match[typeof matchIndex !== 'number' ? 0 : matchIndex]; + return result; } /** @@ -274,8 +282,9 @@ export class Linkifier { * @param {Node} newNode The new node to insert. * @param {string} substring The substring to replace. * @param {number} substringIndex The index of the substring within the string. + * @return The number of nodes to skip when searching for the next uri. */ - private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): void { + private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): number { let node = targetNode; if (node.nodeType !== 3/*Node.TEXT_NODE*/) { node = node.childNodes[0]; @@ -284,7 +293,7 @@ export class Linkifier { // The targetNode will be either a text node or a . The text node // (targetNode or its only-child) needs to be replaced with newNode plus new // text nodes potentially on either side. - if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) { + if (node.childNodes.length === 0 && node.nodeType !== 3/*Node.TEXT_NODE*/) { throw new Error('targetNode must be a text node or only contain a single text node'); } @@ -295,18 +304,23 @@ export class Linkifier { const rightText = fullText.substring(substring.length); const rightTextNode = this._document.createTextNode(rightText); this._replaceNode(node, newNode, rightTextNode); - } else if (substringIndex === targetNode.textContent.length - substring.length) { + return 0; + } + + if (substringIndex === targetNode.textContent.length - substring.length) { // Replace with const leftText = fullText.substring(0, substringIndex); const leftTextNode = this._document.createTextNode(leftText); this._replaceNode(node, leftTextNode, newNode); - } else { - // Replace with - const leftText = fullText.substring(0, substringIndex); - const leftTextNode = this._document.createTextNode(leftText); - const rightText = fullText.substring(substringIndex + substring.length); - const rightTextNode = this._document.createTextNode(rightText); - this._replaceNode(node, leftTextNode, newNode, rightTextNode); + return 1; } + + // Replace with + const leftText = fullText.substring(0, substringIndex); + const leftTextNode = this._document.createTextNode(leftText); + const rightText = fullText.substring(substringIndex + substring.length); + const rightTextNode = this._document.createTextNode(rightText); + this._replaceNode(node, leftTextNode, newNode, rightTextNode); + return 1; } } From d8140097214cc17d093cf9a14b3be5125ed3a571 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 31 Mar 2017 01:48:51 -0700 Subject: [PATCH 197/211] Add tests --- src/Linkifier.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index ca393c21..f70718ea 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -89,6 +89,21 @@ describe('Linkifier', () => { // Allow time for the click to be performed setTimeout(() => done(), 10); }); + + it('should trigger for multiple link matches on one row', done => { + addRow('test test'); + let count = 0; + linkifier.registerLinkMatcher(/test/, () => assert.fail(), { + validationCallback: (url, cb) => { + count += 1; + if (count === 2) { + done(); + } + cb(false); + } + }); + linkifier.linkifyRow(0); + }); }); describe('priority', () => { From 5546baa927e9dd97e527ac6da763f7a9dfcc9d2e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 31 Mar 2017 01:54:21 -0700 Subject: [PATCH 198/211] Fix edge case --- src/Linkifier.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 85d1bd5e..f305945c 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -207,7 +207,7 @@ export class Linkifier { const element = (node); if (element.nodeName === 'A') { // This row has already been linkified - return; + return result; } element.innerHTML = ''; element.appendChild(linkElement); @@ -216,7 +216,7 @@ export class Linkifier { // Matches part of string const nodesAdded = this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); // No need to consider the new nodes - i += nodesAdded - 1; + i += nodesAdded; } result.push(linkElement); From 8c2db8ddb8799771b45500af9dbcc6f4f5fbf08e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 31 Mar 2017 02:10:07 -0700 Subject: [PATCH 199/211] More tests --- src/Linkifier.test.ts | 45 +++++++++++++++++++++++++++++++++++++------ src/Linkifier.ts | 2 +- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index f70718ea..16e388fa 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -36,9 +36,9 @@ describe('Linkifier', () => { }); }); - function addRow(text: string) { + function addRow(html: string) { const element = document.createElement('div'); - element.textContent = text; + element.innerHTML = html; container.appendChild(element); rows.push(element); } @@ -49,7 +49,8 @@ describe('Linkifier', () => { element.dispatchEvent(event); } - function assertLinkifiesEntireRow(uri: string, done: MochaDone) { + describe('http links', () => { + function assertLinkifiesEntireRow(uri: string, done: MochaDone) { addRow(uri); linkifier.linkifyRow(0); setTimeout(() => { @@ -57,12 +58,44 @@ describe('Linkifier', () => { assert.equal((rows[0].firstChild).textContent, uri); done(); }, 0); - } - - describe('http links', () => { + } it('should allow ~ character in URI path', done => assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done)); }); + describe('link matcher', () => { + function assertLinkifiesRow(rowText: string, linkMatcherRegex: RegExp, expectedHtml: string, done: MochaDone) { + addRow(rowText); + linkifier.registerLinkMatcher(linkMatcherRegex, () => {}); + linkifier.linkifyRow(0); + // Allow linkify to happen + setTimeout(() => { + assert.equal(rows[0].innerHTML, expectedHtml); + done(); + }, 0); + } + it('should match a single link', done => { + assertLinkifiesRow('foo', /foo/, '
foo', done); + }); + it('should match a single link at the start of a text node', done => { + assertLinkifiesRow('foo bar', /foo/, 'foo bar', done); + }); + it('should match a single link in the middle of a text node', done => { + assertLinkifiesRow('foo bar baz', /bar/, 'foo bar baz', done); + }); + it('should match a single link at the end of a text node', done => { + assertLinkifiesRow('foo bar', /bar/, 'foo bar', done); + }); + it('should match a link after a link at the start of a text node', done => { + assertLinkifiesRow('foo bar', /foo|bar/, 'foo bar', done); + }); + it('should match a link after a link in the middle of a text node', done => { + assertLinkifiesRow('foo bar baz', /bar|baz/, 'foo bar baz', done); + }); + it('should match a link immediately after a link at the end of a text node', done => { + assertLinkifiesRow('foo barbaz', /bar|baz/, 'foo barbaz', done); + }); + }); + describe('validationCallback', () => { it('should enable link if true', done => { addRow('test'); diff --git a/src/Linkifier.ts b/src/Linkifier.ts index f305945c..b229c775 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -312,7 +312,7 @@ export class Linkifier { const leftText = fullText.substring(0, substringIndex); const leftTextNode = this._document.createTextNode(leftText); this._replaceNode(node, leftTextNode, newNode); - return 1; + return 0; } // Replace with From 26ccf2a3169681c91d0d42e36c71bd49a80987a5 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Fri, 31 Mar 2017 22:16:11 +0200 Subject: [PATCH 200/211] Fix typos in comment --- src/Linkifier.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index d9a16940..0f9d9a21 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -37,8 +37,8 @@ const HYPERTEXT_LINK_MATCHER_ID = 0; export class Linkifier { /** * The time to wait after a row is changed before it is linkified. This prevents - * the costly operation of searching every row multiple times, pntentially a - * huge aount of times. + * the costly operation of searching every row multiple times, potentially a + * huge amount of times. */ protected static TIME_BEFORE_LINKIFY = 200; From aca81c764a188738ae89886bab407d93cd37d136 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 3 Apr 2017 14:49:21 -0700 Subject: [PATCH 201/211] Use setInterval over animation for cursor blink Fixes #625 --- src/xterm.css | 23 ++++++++--------------- src/xterm.js | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index aac95444..a67485e5 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -97,16 +97,9 @@ background-color: transparent; } -.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink .terminal-cursor { - animation: xterm-cursor-blink 1.2s infinite step-end; -} - -@keyframes xterm-cursor-blink { - 0% { } - 50% { - background-color: transparent; - color: inherit; - } +.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink-on .terminal-cursor { + background-color: transparent; + color: inherit; } .terminal.xterm-cursor-style-bar .terminal-cursor, @@ -132,13 +125,13 @@ right: 0; height: 1px; } +.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before, +.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before { + background-color: transparent; +} .terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before, .terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before { - animation: xterm-cursor-non-bar-blink 1.2s infinite step-end; -} -@keyframes xterm-cursor-non-bar-blink { - 0% { background-color: #fff; } - 50% { background-color: transparent; } + background-color: #fff; } .terminal .composition-view { diff --git a/src/xterm.js b/src/xterm.js index 830b8f84..fb690bd4 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -52,6 +52,13 @@ var WRITE_BUFFER_PAUSE_THRESHOLD = 5; */ var WRITE_BATCH_SIZE = 300; +/** + * The time between cursor blinks. This is driven by JS rather than a CSS + * animation due to a bug in Chromium that causes it to use excessive CPU time. + * See https://github.com/Microsoft/vscode/issues/22900 + */ +var CURSOR_BLINK_INTERVAL = 600; + /** * Terminal */ @@ -159,6 +166,7 @@ function Terminal(options) { this.scrollTop = 0; this.scrollBottom = this.rows - 1; this.customKeydownHandler = null; + this.cursorBlinkInterval = null; // modes this.applicationKeypad = false; @@ -423,7 +431,7 @@ Terminal.prototype.setOption = function(key, value) { this[key] = value; this.options[key] = value; switch (key) { - case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break; + case 'cursorBlink': this.setCursorBlinking(value); break; case 'cursorStyle': // Style 'block' applies with no class this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline'); @@ -433,6 +441,25 @@ Terminal.prototype.setOption = function(key, value) { } }; +Terminal.prototype.restartCursorBlinking = function () { + this.setCursorBlinking(this.options.cursorBlink); +} + +Terminal.prototype.setCursorBlinking = function (enabled) { + this.element.classList.toggle('xterm-cursor-blink', enabled); + this.element.classList.remove('xterm-cursor-blink-on'); + if (this.cursorBlinkInterval) { + clearInterval(this.cursorBlinkInterval); + this.cursorBlinkInterval = null; + } + if (enabled) { + var self = this; + this.cursorBlinkInterval = setInterval(function () { + self.element.classList.toggle('xterm-cursor-blink-on'); + }, CURSOR_BLINK_INTERVAL); + } +} + /** * Binds the desired focus behavior on a given terminal object. * @@ -445,6 +472,7 @@ Terminal.bindFocus = function (term) { } term.element.classList.add('focus'); term.showCursor(); + term.restartCursorBlinking.apply(term); Terminal.focus = term; term.emit('focus', {terminal: term}); }); @@ -594,7 +622,7 @@ Terminal.prototype.open = function(parent) { this.element.classList.add('terminal'); this.element.classList.add('xterm'); this.element.classList.add('xterm-theme-' + this.theme); - this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink); + this.setCursorBlinking(this.options.cursorBlink); this.element.style.height this.element.setAttribute('tabindex', 0); @@ -1336,6 +1364,8 @@ Terminal.prototype.keyDown = function(ev) { return false; } + this.restartCursorBlinking(); + if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { if (this.ybase !== this.ydisp) { this.scrollToBottom(); From 0c4ba9fd676f08b29bdb90aa8f6b4f7197bcb307 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 3 Apr 2017 15:09:38 -0700 Subject: [PATCH 202/211] Clear cursor blink interval on blur --- src/xterm.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index fb690bd4..fb7d0cf7 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -443,22 +443,26 @@ Terminal.prototype.setOption = function(key, value) { Terminal.prototype.restartCursorBlinking = function () { this.setCursorBlinking(this.options.cursorBlink); -} +}; Terminal.prototype.setCursorBlinking = function (enabled) { this.element.classList.toggle('xterm-cursor-blink', enabled); - this.element.classList.remove('xterm-cursor-blink-on'); - if (this.cursorBlinkInterval) { - clearInterval(this.cursorBlinkInterval); - this.cursorBlinkInterval = null; - } + this.clearCursorBlinkingInterval(); if (enabled) { var self = this; this.cursorBlinkInterval = setInterval(function () { self.element.classList.toggle('xterm-cursor-blink-on'); }, CURSOR_BLINK_INTERVAL); } -} +}; + +Terminal.prototype.clearCursorBlinkingInterval = function () { + this.element.classList.remove('xterm-cursor-blink-on'); + if (this.cursorBlinkInterval) { + clearInterval(this.cursorBlinkInterval); + this.cursorBlinkInterval = null; + } +}; /** * Binds the desired focus behavior on a given terminal object. @@ -497,6 +501,7 @@ Terminal.bindBlur = function (term) { term.send(C0.ESC + '[O'); } term.element.classList.remove('focus'); + term.clearCursorBlinkingInterval.apply(term); Terminal.focus = null; term.emit('blur', {terminal: term}); }); From 64663bf4a8145b8aa0dc31cb1246fe6d110a6390 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 4 Apr 2017 09:35:52 -0700 Subject: [PATCH 203/211] Fix tests --- src/test/test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/test.js b/src/test/test.js index 716b48c4..1644e580 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -21,7 +21,8 @@ describe('xterm.js', function() { }; xterm.element = { classList: { - toggle: function(){} + toggle: function(){}, + remove: function(){} } }; }); From d2f8f9dc1ade223b9c486e99d9c3b499465fe4d1 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 5 Apr 2017 18:48:57 +0000 Subject: [PATCH 204/211] Bump version to 2.5.0 Signed-off-by: Paris Kasidiaris --- AUTHORS | 5 + bower.json | 2 +- dist/addons/fit/fit.js | 2 +- dist/xterm.css | 25 ++--- dist/xterm.js | 232 ++++++++++++++++++++++++++--------------- dist/xterm.js.map | 2 +- package.json | 2 +- 7 files changed, 168 insertions(+), 102 deletions(-) diff --git a/AUTHORS b/AUTHORS index b0ca2d2f..3d7145b4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -22,16 +22,20 @@ Daniel Imms Daniel Risacher Dan Kaplun Darin Morrison +Edgar Andrés Margffoy Tuay Elliot Saba hiro-su Ian Lewis imoses +InDieTasten Jean Bruenn Jörg Breitbart Lucian Buzzo Maël Nison Martin Wang +Michael Irwin Mikko Karvonen +Nicolas Ramz Paris Kasidiaris Paris Kasidiaris runarberg @@ -42,4 +46,5 @@ Thanasis Daglis Tine Jozelj Tyler Jewell Vincent Woo +yutaka YuviPanda diff --git a/bower.json b/bower.json index dcac3aa4..eb5a0bc2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "xterm.js", - "version": "2.4.0", + "version": "2.5.0", "ignore": ["demo", "test", ".gitignore"], "main": [ "dist/xterm.js", diff --git a/dist/addons/fit/fit.js b/dist/addons/fit/fit.js index 11fc6eb7..46b79e9b 100644 --- a/dist/addons/fit/fit.js +++ b/dist/addons/fit/fit.js @@ -56,7 +56,7 @@ subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace characterWidth = subjectRow.getBoundingClientRect().width; subjectRow.style.display = ''; // Revert style before calculating height, since they differ. - characterHeight = parseInt(subjectRow.offsetHeight); + characterHeight = subjectRow.getBoundingClientRect().height; subjectRow.innerHTML = contentBuffer; rows = parseInt(availableHeight / characterHeight); diff --git a/dist/xterm.css b/dist/xterm.css index b7f120f9..a67485e5 100644 --- a/dist/xterm.css +++ b/dist/xterm.css @@ -86,7 +86,7 @@ text-decoration: none; } -.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { +.terminal.focus:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { background-color: #fff; color: #000; } @@ -97,16 +97,9 @@ background-color: transparent; } -.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink .terminal-cursor { - animation: xterm-cursor-blink 1.2s infinite step-end; -} - -@keyframes xterm-cursor-blink { - 0% { } - 50% { - background-color: transparent; - color: inherit; - } +.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink-on .terminal-cursor { + background-color: transparent; + color: inherit; } .terminal.xterm-cursor-style-bar .terminal-cursor, @@ -132,13 +125,13 @@ right: 0; height: 1px; } +.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before, +.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before { + background-color: transparent; +} .terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before, .terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before { - animation: xterm-cursor-non-bar-blink 1.2s infinite step-end; -} -@keyframes xterm-cursor-non-bar-blink { - 0% { background-color: #fff; } - 50% { background-color: transparent; } + background-color: #fff; } .terminal .composition-view { diff --git a/dist/xterm.js b/dist/xterm.js index e1d81b72..87ee4505 100644 --- a/dist/xterm.js +++ b/dist/xterm.js @@ -1,5 +1,6 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Terminal = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + this._terminal.lines.trimStart(scrollBackSize); + this._terminal.ybase = Math.max(this._terminal.ybase - scrollBackSize, 0); + this._terminal.ydisp = Math.max(this._terminal.ydisp - scrollBackSize, 0); + } break; } }; @@ -1314,6 +1324,7 @@ var wcwidth = (function (opts) { },{"./Charsets":1,"./EscapeSequences":3}],6:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var INVALID_LINK_CLASS = 'xterm-invalid-link'; var protocolClause = '(https?:\\/\\/)'; var domainCharacterSet = '[\\da-z\\.-]+'; @@ -1324,8 +1335,8 @@ var ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; var localHostClause = '(localhost)'; var portClause = '(:\\d{1,5})'; var hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; -var pathClause = '(\\/[\\/\\w\\.\\-%]*)*'; -var queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;\\=\\.\\-]*'; +var pathClause = '(\\/[\\/\\w\\.\\-%~]*)*'; +var queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; var queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; var hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; var negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; @@ -1335,24 +1346,32 @@ var end = ')($|' + negatedPathCharacterSet + ')'; var strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); var HYPERTEXT_LINK_MATCHER_ID = 0; var Linkifier = (function () { - function Linkifier(document, rows) { + function Linkifier() { this._nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; - this._document = document; - this._rows = rows; this._rowTimeoutIds = []; this._linkMatchers = []; this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); } + Linkifier.prototype.attachToDom = function (document, rows) { + this._document = document; + this._rows = rows; + }; Linkifier.prototype.linkifyRow = function (rowIndex) { + if (!this._document) { + return; + } var timeoutId = this._rowTimeoutIds[rowIndex]; if (timeoutId) { clearTimeout(timeoutId); } this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), Linkifier.TIME_BEFORE_LINKIFY); }; - Linkifier.prototype.attachHypertextLinkHandler = function (handler) { + Linkifier.prototype.setHypertextLinkHandler = function (handler) { this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; }; + Linkifier.prototype.setHypertextValidationCallback = function (callback) { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback; + }; Linkifier.prototype.registerLinkMatcher = function (regex, handler, options) { if (options === void 0) { options = {}; } if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { @@ -1397,35 +1416,42 @@ var Linkifier = (function () { return; } var text = row.textContent; - var _loop_1 = function (i) { - var matcher = this_1._linkMatchers[i]; - var uri = this_1._findLinkMatch(text, matcher.regex, matcher.matchIndex); - if (uri) { - var linkElement_1 = this_1._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID); - if (linkElement_1 && matcher.validationCallback) { - matcher.validationCallback(uri, function (isValid) { - if (!isValid) { - linkElement_1.classList.add(INVALID_LINK_CLASS); - } - }); - } - return { value: void 0 }; - } - }; - var this_1 = this; for (var i = 0; i < this._linkMatchers.length; i++) { - var state_1 = _loop_1(i); - if (typeof state_1 === "object") - return state_1.value; + var matcher = this._linkMatchers[i]; + var linkElements = this._doLinkifyRow(row, matcher); + if (linkElements.length > 0) { + if (matcher.validationCallback) { + var _loop_1 = function (j) { + var element = linkElements[j]; + matcher.validationCallback(element.textContent, element, function (isValid) { + if (!isValid) { + element.classList.add(INVALID_LINK_CLASS); + } + }); + }; + for (var j = 0; j < linkElements.length; j++) { + _loop_1(j); + } + } + return; + } } }; - Linkifier.prototype._doLinkifyRow = function (rowIndex, uri, handler, isHttpLinkMatcher) { - var nodes = this._rows[rowIndex].childNodes; + Linkifier.prototype._doLinkifyRow = function (row, matcher) { + var result = []; + var isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID; + var nodes = row.childNodes; + var match = row.textContent.match(matcher.regex); + if (!match || match.length === 0) { + return result; + } + var uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + var rowStartIndex = match.index + uri.length; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; var searchIndex = node.textContent.indexOf(uri); if (searchIndex >= 0) { - var linkElement = this._createAnchorElement(uri, handler, isHttpLinkMatcher); + var linkElement = this._createAnchorElement(uri, matcher.handler, isHttpLinkMatcher); if (node.textContent.length === uri.length) { if (node.nodeType === 3) { this._replaceNode(node, linkElement); @@ -1433,29 +1459,31 @@ var Linkifier = (function () { else { var element = node; if (element.nodeName === 'A') { - return; + return result; } element.innerHTML = ''; element.appendChild(linkElement); } } else { - this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); + var nodesAdded = this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex); + i += nodesAdded; } - return linkElement; + result.push(linkElement); + match = row.textContent.substring(rowStartIndex).match(matcher.regex); + if (!match || match.length === 0) { + return result; + } + uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + rowStartIndex += match.index + uri.length; } } - }; - Linkifier.prototype._findLinkMatch = function (text, regex, matchIndex) { - var match = text.match(regex); - if (!match || match.length === 0) { - return null; - } - return match[typeof matchIndex !== 'number' ? 0 : matchIndex]; + return result; }; Linkifier.prototype._createAnchorElement = function (uri, handler, isHypertextLinkHandler) { var element = this._document.createElement('a'); element.textContent = uri; + element.draggable = false; if (isHypertextLinkHandler) { element.href = uri; element.target = '_blank'; @@ -1491,27 +1519,28 @@ var Linkifier = (function () { if (node.nodeType !== 3) { node = node.childNodes[0]; } - if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) { + if (node.childNodes.length === 0 && node.nodeType !== 3) { throw new Error('targetNode must be a text node or only contain a single text node'); } var fullText = node.textContent; if (substringIndex === 0) { - var rightText = fullText.substring(substring.length); - var rightTextNode = this._document.createTextNode(rightText); - this._replaceNode(node, newNode, rightTextNode); + var rightText_1 = fullText.substring(substring.length); + var rightTextNode_1 = this._document.createTextNode(rightText_1); + this._replaceNode(node, newNode, rightTextNode_1); + return 0; } - else if (substringIndex === targetNode.textContent.length - substring.length) { - var leftText = fullText.substring(0, substringIndex); - var leftTextNode = this._document.createTextNode(leftText); - this._replaceNode(node, leftTextNode, newNode); - } - else { - var leftText = fullText.substring(0, substringIndex); - var leftTextNode = this._document.createTextNode(leftText); - var rightText = fullText.substring(substringIndex + substring.length); - var rightTextNode = this._document.createTextNode(rightText); - this._replaceNode(node, leftTextNode, newNode, rightTextNode); + if (substringIndex === targetNode.textContent.length - substring.length) { + var leftText_1 = fullText.substring(0, substringIndex); + var leftTextNode_1 = this._document.createTextNode(leftText_1); + this._replaceNode(node, leftTextNode_1, newNode); + return 0; } + var leftText = fullText.substring(0, substringIndex); + var leftTextNode = this._document.createTextNode(leftText); + var rightText = fullText.substring(substringIndex + substring.length); + var rightTextNode = this._document.createTextNode(rightText); + this._replaceNode(node, leftTextNode, newNode, rightTextNode); + return 1; }; return Linkifier; }()); @@ -1522,6 +1551,7 @@ exports.Linkifier = Linkifier; },{}],7:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var EscapeSequences_1 = require("./EscapeSequences"); var Charsets_1 = require("./Charsets"); var normalStateHandler = {}; @@ -1997,6 +2027,7 @@ exports.Parser = Parser; },{"./Charsets":1,"./EscapeSequences":3}],8:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var MAX_REFRESH_FRAME_SKIP = 5; var FLAGS; (function (FLAGS) { @@ -2015,7 +2046,7 @@ var Renderer = (function () { this._refreshFramesSkipped = 0; this._refreshAnimationFrame = null; if (brokenBold === null) { - brokenBold = checkBoldBroken(this._terminal.document); + brokenBold = checkBoldBroken(this._terminal.element); } } Renderer.prototype.queueRefresh = function (start, end) { @@ -2192,22 +2223,25 @@ var Renderer = (function () { return Renderer; }()); exports.Renderer = Renderer; -function checkBoldBroken(document) { - var body = document.getElementsByTagName('body')[0]; +function checkBoldBroken(terminal) { + var document = terminal.ownerDocument; var el = document.createElement('span'); el.innerHTML = 'hello world'; - body.appendChild(el); - var w1 = el.scrollWidth; + terminal.appendChild(el); + var w1 = el.offsetWidth; + var h1 = el.offsetHeight; el.style.fontWeight = 'bold'; - var w2 = el.scrollWidth; - body.removeChild(el); - return w1 !== w2; + var w2 = el.offsetWidth; + var h2 = el.offsetHeight; + terminal.removeChild(el); + return w1 !== w2 || h1 !== h2; } },{}],9:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var Viewport = (function () { function Viewport(terminal, viewportElement, scrollArea, charMeasure) { var _this = this; @@ -2285,6 +2319,7 @@ exports.Viewport = Viewport; },{}],10:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); function prepareTextForClipboard(text) { var space = String.fromCharCode(32), nonBreakingSpace = String.fromCharCode(160), allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'), processedText = text.split('\n').map(function (line) { var processedLine = line.replace(/\s+$/g, '').replace(allNonBreakingSpaces, space); @@ -2366,6 +2401,7 @@ exports.rightClickHandler = rightClickHandler; },{}],11:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var Generic_1 = require("./Generic"); var isNode = (typeof navigator === 'undefined') ? true : false; var userAgent = (isNode) ? 'node' : navigator.userAgent; @@ -2381,11 +2417,17 @@ exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], },{"./Generic":14}],12:[function(require,module,exports){ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); var EventEmitter_js_1 = require("../EventEmitter.js"); var CharMeasure = (function (_super) { __extends(CharMeasure, _super); @@ -2444,6 +2486,7 @@ exports.CharMeasure = CharMeasure; },{"../EventEmitter.js":4}],13:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var CircularList = (function () { function CircularList(maxLength) { this._array = new Array(maxLength); @@ -2582,6 +2625,7 @@ exports.CircularList = CircularList; },{}],14:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); function contains(arr, el) { return arr.indexOf(el) >= 0; } @@ -2592,6 +2636,7 @@ exports.contains = contains; },{}],15:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var CompositionHelper_1 = require("./CompositionHelper"); var EventEmitter_1 = require("./EventEmitter"); var Viewport_1 = require("./Viewport"); @@ -2607,6 +2652,7 @@ var Browser = require("./utils/Browser"); var document = (typeof window != 'undefined') ? window.document : null; var WRITE_BUFFER_PAUSE_THRESHOLD = 5; var WRITE_BATCH_SIZE = 300; +var CURSOR_BLINK_INTERVAL = 600; function Terminal(options) { var self = this; if (!(this instanceof Terminal)) { @@ -2664,6 +2710,7 @@ function Terminal(options) { this.scrollTop = 0; this.scrollBottom = this.rows - 1; this.customKeydownHandler = null; + this.cursorBlinkInterval = null; this.applicationKeypad = false; this.applicationCursor = false; this.originMode = false; @@ -2702,8 +2749,7 @@ function Terminal(options) { this.inputHandler = new InputHandler_1.InputHandler(this); this.parser = new Parser_1.Parser(this.inputHandler, this); this.renderer = this.renderer || null; - this.linkifier = this.linkifier || null; - ; + this.linkifier = this.linkifier || new Linkifier_1.Linkifier(); this.writeBuffer = []; this.writeInProgress = false; this.xoffSentToCatchUp = false; @@ -2835,7 +2881,7 @@ Terminal.prototype.setOption = function (key, value) { this.options[key] = value; switch (key) { case 'cursorBlink': - this.element.classList.toggle('xterm-cursor-blink', value); + this.setCursorBlinking(value); break; case 'cursorStyle': this.element.classList.toggle("xterm-cursor-style-underline", value === 'underline'); @@ -2846,6 +2892,26 @@ Terminal.prototype.setOption = function (key, value) { break; } }; +Terminal.prototype.restartCursorBlinking = function () { + this.setCursorBlinking(this.options.cursorBlink); +}; +Terminal.prototype.setCursorBlinking = function (enabled) { + this.element.classList.toggle('xterm-cursor-blink', enabled); + this.clearCursorBlinkingInterval(); + if (enabled) { + var self = this; + this.cursorBlinkInterval = setInterval(function () { + self.element.classList.toggle('xterm-cursor-blink-on'); + }, CURSOR_BLINK_INTERVAL); + } +}; +Terminal.prototype.clearCursorBlinkingInterval = function () { + this.element.classList.remove('xterm-cursor-blink-on'); + if (this.cursorBlinkInterval) { + clearInterval(this.cursorBlinkInterval); + this.cursorBlinkInterval = null; + } +}; Terminal.bindFocus = function (term) { on(term.textarea, 'focus', function (ev) { if (term.sendFocus) { @@ -2853,6 +2919,7 @@ Terminal.bindFocus = function (term) { } term.element.classList.add('focus'); term.showCursor(); + term.restartCursorBlinking.apply(term); Terminal.focus = term; term.emit('focus', { terminal: term }); }); @@ -2867,6 +2934,7 @@ Terminal.bindBlur = function (term) { term.send(EscapeSequences_1.C0.ESC + '[O'); } term.element.classList.remove('focus'); + term.clearCursorBlinkingInterval.apply(term); Terminal.focus = null; term.emit('blur', { terminal: term }); }); @@ -2953,7 +3021,7 @@ Terminal.prototype.open = function (parent) { this.element.classList.add('terminal'); this.element.classList.add('xterm'); this.element.classList.add('xterm-theme-' + this.theme); - this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink); + this.setCursorBlinking(this.options.cursorBlink); this.element.style.height; this.element.setAttribute('tabindex', 0); this.viewportElement = document.createElement('div'); @@ -2966,7 +3034,7 @@ Terminal.prototype.open = function (parent) { this.rowContainer.classList.add('xterm-rows'); this.element.appendChild(this.rowContainer); this.children = []; - this.linkifier = new Linkifier_1.Linkifier(document, this.children); + this.linkifier.attachToDom(document, this.children); this.helperContainer = document.createElement('div'); this.helperContainer.classList.add('xterm-helpers'); this.element.appendChild(this.helperContainer); @@ -3395,11 +3463,18 @@ Terminal.prototype.writeln = function (data) { Terminal.prototype.attachCustomKeydownHandler = function (customKeydownHandler) { this.customKeydownHandler = customKeydownHandler; }; -Terminal.prototype.attachHypertextLinkHandler = function (handler) { +Terminal.prototype.setHypertextLinkHandler = function (handler) { if (!this.linkifier) { throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); } - this.linkifier.attachHypertextLinkHandler(handler); + this.linkifier.setHypertextLinkHandler(handler); + this.refresh(0, this.rows - 1); +}; +Terminal.prototype.setHypertextValidationCallback = function (handler) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called'); + } + this.linkifier.setHypertextValidationCallback(handler); this.refresh(0, this.rows - 1); }; Terminal.prototype.registerLinkMatcher = function (regex, handler, options) { @@ -3420,6 +3495,7 @@ Terminal.prototype.keyDown = function (ev) { if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) { return false; } + this.restartCursorBlinking(); if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { if (this.ybase !== this.ydisp) { this.scrollToBottom(); @@ -3814,14 +3890,6 @@ Terminal.prototype.resize = function (x, y) { } } } - else { - i = this.lines.length; - while (i--) { - while (this.lines.get(i).length > x) { - this.lines.get(i).pop(); - } - } - } this.cols = x; this.setupStops(this.cols); j = this.rows; diff --git a/dist/xterm.js.map b/dist/xterm.js.map index 90021b21..b7f0475e 100644 --- a/dist/xterm.js.map +++ b/dist/xterm.js.map @@ -1 +1 @@ -{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/Linkifier.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { Linkifier } from './Linkifier';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n this.linkifier = this.linkifier || null;;\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n term.on('refresh', function (data) {\n term.queueLinkification(data.start, data.end)\n });\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n this.linkifier = new Linkifier(document, this.children);\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(document, this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n x = Math.ceil(x / self.charMeasure.width);\n y = Math.ceil(y / self.charMeasure.height);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Queues linkification for the specified rows.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\nTerminal.prototype.queueLinkification = function(start, end) {\n if (this.linkifier) {\n for (let i = start; i <= end; i++) {\n this.linkifier.linkifyRow(i);\n }\n }\n}\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Attaches a http(s) link handler, forcing web links to behave differently to\n * regular tags. This will trigger a refresh as links potentially need to be\n * reconstructed. Calling this with null will remove the handler.\n * @param {LinkHandler} handler The handler callback function.\n */\nTerminal.prototype.attachHypertextLinkHandler = function(handler) {\n if (!this.linkifier) {\n throw new Error('Cannot attach a hypertext link handler before Terminal.open is called');\n }\n this.linkifier.attachHypertextLinkHandler(handler);\n // Refresh to force links to refresh\n this.refresh(0, this.rows - 1);\n}\n\n/**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param {RegExp} regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param {LinkHandler} handler The callback when the link is called.\n * @param {LinkMatcherOptions} [options] Options for the link matcher.\n * @return {number} The ID of the new matcher, this can be used to deregister.\n */\nTerminal.prototype.registerLinkMatcher = function(regex, handler, options) {\n if (this.linkifier) {\n var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);\n this.refresh(0, this.rows - 1);\n return matcherId;\n }\n}\n\n/**\n * Deregisters a link matcher if it has been registered.\n * @param {number} matcherId The link matcher's ID (returned after register)\n */\nTerminal.prototype.deregisterLinkMatcher = function(matcherId) {\n if (this.linkifier) {\n if (this.linkifier.deregisterLinkMatcher(matcherId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n } else { // (j > x)\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length > x) {\n this.lines.get(i).pop();\n }\n }\n }\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _document: Document;\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(document: Document, parentElement: HTMLElement) {\n super();\n this._document = document;\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = this._document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n // Perform this async to ensure the CharMeasure is ready.\n setTimeout(() => this.syncScrollArea(), 0);\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).document);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(document) {\n const body = document.getElementsByTagName('body')[0];\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n body.appendChild(el);\n const w1 = el.scrollWidth;\n el.style.fontWeight = 'bold';\n const w2 = el.scrollWidth;\n body.removeChild(el);\n return w1 !== w2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { LinkMatcherOptions } from './Interfaces';\nimport { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types';\n\nconst INVALID_LINK_CLASS = 'xterm-invalid-link';\n\nconst protocolClause = '(https?:\\\\/\\\\/)';\nconst domainCharacterSet = '[\\\\da-z\\\\.-]+';\nconst negatedDomainCharacterSet = '[^\\\\da-z\\\\.-]+';\nconst domainBodyClause = '(' + domainCharacterSet + ')';\nconst tldClause = '([a-z\\\\.]{2,6})';\nconst ipClause = '((\\\\d{1,3}\\\\.){3}\\\\d{1,3})';\nconst localHostClause = '(localhost)';\nconst portClause = '(:\\\\d{1,5})';\nconst hostClause = '((' + domainBodyClause + '\\\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';\nconst pathClause = '(\\\\/[\\\\/\\\\w\\\\.\\\\-%]*)*';\nconst queryStringHashFragmentCharacterSet = '[0-9\\\\w\\\\[\\\\]\\\\(\\\\)\\\\/\\\\?\\\\!#@$%&\\'*+,:;\\\\=\\\\.\\\\-]*';\nconst queryStringClause = '(\\\\?' + queryStringHashFragmentCharacterSet + ')?';\nconst hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';\nconst negatedPathCharacterSet = '[^\\\\/\\\\w\\\\.\\\\-%]+';\nconst bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause;\nconst start = '(?:^|' + negatedDomainCharacterSet + ')(';\nconst end = ')($|' + negatedPathCharacterSet + ')';\nconst strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end);\n\n/**\n * The ID of the built in http(s) link matcher.\n */\nconst HYPERTEXT_LINK_MATCHER_ID = 0;\n\n/**\n * The Linkifier applies links to rows shortly after they have been refreshed.\n */\nexport class Linkifier {\n /**\n * The time to wait after a row is changed before it is linkified. This prevents\n * the costly operation of searching every row multiple times, pntentially a\n * huge aount of times.\n */\n protected static TIME_BEFORE_LINKIFY = 200;\n\n protected _linkMatchers: LinkMatcher[];\n\n private _document: Document;\n private _rows: HTMLElement[];\n private _rowTimeoutIds: number[];\n private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;\n\n constructor(document: Document, rows: HTMLElement[]) {\n this._document = document;\n this._rows = rows;\n this._rowTimeoutIds = [];\n this._linkMatchers = [];\n this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });\n }\n\n /**\n * Queues a row for linkification.\n * @param {number} rowIndex The index of the row to linkify.\n */\n public linkifyRow(rowIndex: number): void {\n const timeoutId = this._rowTimeoutIds[rowIndex];\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), Linkifier.TIME_BEFORE_LINKIFY);\n }\n\n /**\n * Attaches a handler for hypertext links, overriding default behavior\n * for standard http(s) links.\n * @param {LinkHandler} handler The handler to use, this can be cleared with\n * null.\n */\n public attachHypertextLinkHandler(handler: LinkMatcherHandler): void {\n this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler;\n }\n\n /**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param {RegExp} regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param {LinkHandler} handler The callback when the link is called.\n * @param {LinkMatcherOptions} [options] Options for the link matcher.\n * @return {number} The ID of the new matcher, this can be used to deregister.\n */\n public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: LinkMatcherOptions = {}): number {\n if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) {\n throw new Error('handler must be defined');\n }\n const matcher: LinkMatcher = {\n id: this._nextLinkMatcherId++,\n regex,\n handler,\n matchIndex: options.matchIndex,\n validationCallback: options.validationCallback,\n priority: options.priority || 0\n };\n this._addLinkMatcherToList(matcher);\n return matcher.id;\n }\n\n /**\n * Inserts a link matcher to the list in the correct position based on the\n * priority of each link matcher. New link matchers of equal priority are\n * considered after older link matchers.\n * @param matcher The link matcher to be added.\n */\n private _addLinkMatcherToList(matcher: LinkMatcher): void {\n if (this._linkMatchers.length === 0) {\n this._linkMatchers.push(matcher);\n return;\n }\n\n for (let i = this._linkMatchers.length - 1; i >= 0; i--) {\n if (matcher.priority <= this._linkMatchers[i].priority) {\n this._linkMatchers.splice(i + 1, 0, matcher);\n return;\n }\n }\n\n this._linkMatchers.splice(0, 0, matcher);\n }\n\n /**\n * Deregisters a link matcher if it has been registered.\n * @param {number} matcherId The link matcher's ID (returned after register)\n * @return {boolean} Whether a link matcher was found and deregistered.\n */\n public deregisterLinkMatcher(matcherId: number): boolean {\n // ID 0 is the hypertext link matcher which cannot be deregistered\n for (let i = 1; i < this._linkMatchers.length; i++) {\n if (this._linkMatchers[i].id === matcherId) {\n this._linkMatchers.splice(i, 1);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Linkifies a row.\n * @param {number} rowIndex The index of the row to linkify.\n */\n private _linkifyRow(rowIndex: number): void {\n const row = this._rows[rowIndex];\n if (!row) {\n return;\n }\n const text = row.textContent;\n for (let i = 0; i < this._linkMatchers.length; i++) {\n const matcher = this._linkMatchers[i];\n const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex);\n if (uri) {\n const linkElement = this._doLinkifyRow(rowIndex, uri, matcher.handler, matcher.id === HYPERTEXT_LINK_MATCHER_ID);\n // Fire validation callback\n if (linkElement && matcher.validationCallback) {\n matcher.validationCallback(uri, isValid => {\n if (!isValid) {\n linkElement.classList.add(INVALID_LINK_CLASS);\n }\n });\n }\n // Only allow a single LinkMatcher to trigger on any given row.\n return;\n }\n }\n }\n\n /**\n * Linkifies a row given a specific handler.\n * @param {number} rowIndex The index of the row to linkify.\n * @param {string} uri The uri that has been found.\n * @param {handler} handler The handler to trigger when the link is triggered.\n * @return The link element if it was added, otherwise undefined.\n */\n private _doLinkifyRow(rowIndex: number, uri: string, handler: LinkMatcherHandler, isHttpLinkMatcher: boolean): HTMLElement {\n // Iterate over nodes as we want to consider text nodes\n const nodes = this._rows[rowIndex].childNodes;\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const searchIndex = node.textContent.indexOf(uri);\n if (searchIndex >= 0) {\n const linkElement = this._createAnchorElement(uri, handler, isHttpLinkMatcher);\n if (node.textContent.length === uri.length) {\n // Matches entire string\n\n if (node.nodeType === 3 /*Node.TEXT_NODE*/) {\n this._replaceNode(node, linkElement);\n } else {\n const element = (node);\n if (element.nodeName === 'A') {\n // This row has already been linkified\n return;\n }\n element.innerHTML = '';\n element.appendChild(linkElement);\n }\n } else {\n // Matches part of string\n this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex);\n }\n return linkElement;\n }\n }\n }\n\n /**\n * Finds a link match in a piece of text.\n * @param {string} text The text to search.\n * @param {number} matchIndex The regex match index of the link.\n * @return {string} The matching URI or null if not found.\n */\n private _findLinkMatch(text: string, regex: RegExp, matchIndex?: number): string {\n const match = text.match(regex);\n if (!match || match.length === 0) {\n return null;\n }\n return match[typeof matchIndex !== 'number' ? 0 : matchIndex];\n }\n\n /**\n * Creates a link anchor element.\n * @param {string} uri The uri of the link.\n * @return {HTMLAnchorElement} The link.\n */\n private _createAnchorElement(uri: string, handler: LinkMatcherHandler, isHypertextLinkHandler: boolean): HTMLAnchorElement {\n const element = this._document.createElement('a');\n element.textContent = uri;\n if (isHypertextLinkHandler) {\n element.href = uri;\n // Force link on another tab so work is not lost\n element.target = '_blank';\n element.addEventListener('click', (event: MouseEvent) => {\n if (handler) {\n return handler(event, uri);\n }\n });\n } else {\n element.addEventListener('click', (event: MouseEvent) => {\n // Don't execute the handler if the link is flagged as invalid\n if (element.classList.contains(INVALID_LINK_CLASS)) {\n return;\n }\n return handler(event, uri);\n });\n }\n return element;\n }\n\n /**\n * Replace a node with 1 or more other nodes.\n * @param {Node} oldNode The node to replace.\n * @param {Node[]} newNodes The new nodes to insert in order.\n */\n private _replaceNode(oldNode: Node, ...newNodes: Node[]): void {\n const parent = oldNode.parentNode;\n for (let i = 0; i < newNodes.length; i++) {\n parent.insertBefore(newNodes[i], oldNode);\n }\n parent.removeChild(oldNode);\n }\n\n /**\n * Replace a substring within a node with a new node.\n * @param {Node} targetNode The target node; either a text node or a \n * containing a single text node.\n * @param {Node} newNode The new node to insert.\n * @param {string} substring The substring to replace.\n * @param {number} substringIndex The index of the substring within the string.\n */\n private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): void {\n let node = targetNode;\n if (node.nodeType !== 3/*Node.TEXT_NODE*/) {\n node = node.childNodes[0];\n }\n\n // The targetNode will be either a text node or a . The text node\n // (targetNode or its only-child) needs to be replaced with newNode plus new\n // text nodes potentially on either side.\n if (node.childNodes.length === 0 && node.nodeType !== Node.TEXT_NODE) {\n throw new Error('targetNode must be a text node or only contain a single text node');\n }\n\n const fullText = node.textContent;\n\n if (substringIndex === 0) {\n // Replace with \n const rightText = fullText.substring(substring.length);\n const rightTextNode = this._document.createTextNode(rightText);\n this._replaceNode(node, newNode, rightTextNode);\n } else if (substringIndex === targetNode.textContent.length - substring.length) {\n // Replace with \n const leftText = fullText.substring(0, substringIndex);\n const leftTextNode = this._document.createTextNode(leftText);\n this._replaceNode(node, leftTextNode, newNode);\n } else {\n // Replace with \n const leftText = fullText.substring(0, substringIndex);\n const leftTextNode = this._document.createTextNode(leftText);\n const rightText = fullText.substring(substringIndex + substring.length);\n const rightTextNode = this._document.createTextNode(rightText);\n this._replaceNode(node, leftTextNode, newNode, rightTextNode);\n }\n }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n ; // no saved lines\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * @license MIT\n */\n\n/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"AeAA;;ADSa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AD3OA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AACA;AAAA;AApNa;;;;;;ADRb;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAAC;;;;;;ADtEA;AAED;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA9Da;;;;;;ADJb;AACA;AASA;AAEA;AAAA;AAAA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAkEA;AAEA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAj7Ca;AAm7Cb;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADliDA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAKA;AAeA;AAFA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;;AAhBA;AAAA;;;AAgBA;AACA;AASA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA5QmB;AANN;;;;;;ADhCb;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAKA;AACA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAIA;AACA;AAGA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AAAA;AArda;;;;;;AD3Jb;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAC;AAED;AAEA;AAMA;AAAA;AAJA;AACA;AACA;AAKA;AACA;AACA;AAKA;AAQA;AACA;AACA;AACA;AACA;AACA;AAMA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAuBA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AAGA;AAAA;AACA;AAEA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAtQa;AA2Qb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ADpSA;AAYA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AA/Ga;;;;;;ADcb;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAbA;AAmBA;AAGA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAbA;AAoBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAtBA;AAqCA;AACA;AAMA;AACA;AAGA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApDA;;;;;;AD/FA;AAEA;AACA;AACA;AAEa;AACA;AAKA;AACA;AACA;AACA;;;;;;;;;;;ADhBb;AAKA;AAAA;AAOA;AAAA;AAEA;AACA;;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAnDa;;;;;;ADJb;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAXA;AAaA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAWA;AAAA;AACA;AACA;;;AAAA;AAUA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AAhLa;;;;;;ADKb;AACA;AACA;AAFA;AAEC;;;;;;ADDD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAgBA;AAOA;AAMA;AAkBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAIA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAMA;AAKA;AAKA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AAQA;AAGA;AAGA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAKA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAIA;AAGA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAOA;AACA;AAQA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAYA;AACA;AAKA;AACA;AAIA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AACA;AAGA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAGA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AAGA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAQA;AACA;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAOA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AASA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAQA;AACA;AACA;AAEA;;;"} \ No newline at end of file +{"version":3,"file":"xterm.js","sources":["../src/xterm.js","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Renderer.ts","../src/Parser.ts","../src/Linkifier.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * xterm.js: xterm, in the browser\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n * @license MIT\n */\n\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './Renderer';\nimport { Linkifier } from './Linkifier';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport * as Keyboard from './utils/Keyboard';\nimport { CHARSETS } from './Charsets';\n\n/**\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\n// Let it work inside Node.js for automated testing purposes.\nvar document = (typeof window != 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nvar WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nvar WRITE_BATCH_SIZE = 300;\n\n/**\n * The time between cursor blinks. This is driven by JS rather than a CSS\n * animation due to a bug in Chromium that causes it to use excessive CPU time.\n * See https://github.com/Microsoft/vscode/issues/22900\n */\nvar CURSOR_BLINK_INTERVAL = 600;\n\n/**\n * Terminal\n */\n\n/**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\nfunction Terminal(options) {\n var self = this;\n\n if (!(this instanceof Terminal)) {\n return new Terminal(arguments[0], arguments[1], arguments[2]);\n }\n\n self.browser = Browser;\n self.cancel = Terminal.cancel;\n\n EventEmitter.call(this);\n\n if (typeof options === 'number') {\n options = {\n cols: arguments[0],\n rows: arguments[1],\n handler: arguments[2]\n };\n }\n\n options = options || {};\n\n\n Object.keys(Terminal.defaults).forEach(function(key) {\n if (options[key] == null) {\n options[key] = Terminal.options[key];\n\n if (Terminal[key] !== Terminal.defaults[key]) {\n options[key] = Terminal[key];\n }\n }\n self[key] = options[key];\n });\n\n if (options.colors.length === 8) {\n options.colors = options.colors.concat(Terminal._colors.slice(8));\n } else if (options.colors.length === 16) {\n options.colors = options.colors.concat(Terminal._colors.slice(16));\n } else if (options.colors.length === 10) {\n options.colors = options.colors.slice(0, -2).concat(\n Terminal._colors.slice(8, -2), options.colors.slice(-2));\n } else if (options.colors.length === 18) {\n options.colors = options.colors.concat(\n Terminal._colors.slice(16, -2), options.colors.slice(-2));\n }\n this.colors = options.colors;\n\n this.options = options;\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n this.parent = options.body || options.parent || (\n document ? document.getElementsByTagName('body')[0] : null\n );\n\n this.cols = options.cols || options.geometry[0];\n this.rows = options.rows || options.geometry[1];\n this.geometry = [this.cols, this.rows];\n\n if (options.handler) {\n this.on('data', options.handler);\n }\n\n /**\n * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n * buffer\n */\n this.ybase = 0;\n\n /**\n * The scroll position of the viewport\n */\n this.ydisp = 0;\n\n /**\n * The cursor's x position after ybase\n */\n this.x = 0;\n\n /**\n * The cursor's y position after ybase\n */\n this.y = 0;\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.convertEol;\n this.queue = '';\n this.scrollTop = 0;\n this.scrollBottom = this.rows - 1;\n this.customKeydownHandler = null;\n this.cursorBlinkInterval = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.normal = null;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n this.charsets = [null];\n\n // mouse properties\n this.decLocator;\n this.x10Mouse;\n this.vt200Mouse;\n this.vt300Mouse;\n this.normalMouse;\n this.mouseEvents;\n this.sendFocus;\n this.utfMouse;\n this.sgrMouse;\n this.urxvtMouse;\n\n // misc\n this.element;\n this.children;\n this.refreshStart;\n this.refreshEnd;\n this.savedX;\n this.savedY;\n this.savedCols;\n\n // stream\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = this.defAttr;\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a Terminal.reset call.\n this.renderer = this.renderer || null;\n this.linkifier = this.linkifier || new Linkifier();\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n this.xoffSentToCatchUp = false;\n\n /** Whether writing has been stopped as a result of XOFF */\n this.writeStopped = false;\n\n // leftover surrogate high from previous write invocation\n this.surrogate_high = '';\n\n /**\n * An array of all lines in the entire buffer, including the prompt. The lines are array of\n * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n */\n this.lines = new CircularList(this.scrollback);\n var i = this.rows;\n while (i--) {\n this.lines.push(this.blankLine());\n }\n\n this.tabs;\n this.setupStops();\n\n // Store if user went browsing history in scrollback\n this.userScrolling = false;\n}\n\ninherits(Terminal, EventEmitter);\n\n/**\n * back_color_erase feature for xterm.\n */\nTerminal.prototype.eraseAttr = function() {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n};\n\n/**\n * Colors\n */\n\n// Colors 0-15\nTerminal.tangoColors = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors = (function() {\n var colors = Terminal.tangoColors.slice()\n , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]\n , i;\n\n // 16-231\n i = 0;\n for (; i < 216; i++) {\n out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);\n }\n\n // 232-255 (grey)\n i = 0;\n for (; i < 24; i++) {\n r = 8 + i * 10;\n out(r, r, r);\n }\n\n function out(r, g, b) {\n colors.push('#' + hex(r) + hex(g) + hex(b));\n }\n\n function hex(c) {\n c = c.toString(16);\n return c.length < 2 ? '0' + c : c;\n }\n\n return colors;\n})();\n\nTerminal._colors = Terminal.colors.slice();\n\nTerminal.vcolors = (function() {\n var out = []\n , colors = Terminal.colors\n , i = 0\n , color;\n\n for (; i < 256; i++) {\n color = parseInt(colors[i].substring(1), 16);\n out.push([\n (color >> 16) & 0xff,\n (color >> 8) & 0xff,\n color & 0xff\n ]);\n }\n\n return out;\n})();\n\n/**\n * Options\n */\n\nTerminal.defaults = {\n colors: Terminal.colors,\n theme: 'default',\n convertEol: false,\n termName: 'xterm',\n geometry: [80, 24],\n cursorBlink: false,\n cursorStyle: 'block',\n visualBell: false,\n popOnBell: false,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8\n // programFeatures: false,\n // focusKeys: false,\n};\n\nTerminal.options = {};\n\nTerminal.focus = null;\n\neach(keys(Terminal.defaults), function(key) {\n Terminal[key] = Terminal.defaults[key];\n Terminal.options[key] = Terminal.defaults[key];\n});\n\n/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\nTerminal.prototype.focus = function() {\n return this.textarea.focus();\n};\n\n/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\nTerminal.prototype.getOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n};\n\n/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */\nTerminal.prototype.setOption = function(key, value) {\n if (!(key in Terminal.defaults)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'scrollback':\n if (this.options[key] !== value) {\n if (this.lines.length > value) {\n const amountToTrim = this.lines.length - value;\n const needsRefresh = (this.ydisp - amountToTrim < 0);\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n this.lines.maxLength = value;\n this.viewport.syncScrollArea();\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'cursorBlink': this.setCursorBlinking(value); break;\n case 'cursorStyle':\n // Style 'block' applies with no class\n this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');\n this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');\n break;\n case 'tabStopWidth': this.setupStops(); break;\n }\n};\n\nTerminal.prototype.restartCursorBlinking = function () {\n this.setCursorBlinking(this.options.cursorBlink);\n};\n\nTerminal.prototype.setCursorBlinking = function (enabled) {\n this.element.classList.toggle('xterm-cursor-blink', enabled);\n this.clearCursorBlinkingInterval();\n if (enabled) {\n var self = this;\n this.cursorBlinkInterval = setInterval(function () {\n self.element.classList.toggle('xterm-cursor-blink-on');\n }, CURSOR_BLINK_INTERVAL);\n }\n};\n\nTerminal.prototype.clearCursorBlinkingInterval = function () {\n this.element.classList.remove('xterm-cursor-blink-on');\n if (this.cursorBlinkInterval) {\n clearInterval(this.cursorBlinkInterval);\n this.cursorBlinkInterval = null;\n }\n};\n\n/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindFocus = function (term) {\n on(term.textarea, 'focus', function (ev) {\n if (term.sendFocus) {\n term.send(C0.ESC + '[I');\n }\n term.element.classList.add('focus');\n term.showCursor();\n term.restartCursorBlinking.apply(term);\n Terminal.focus = term;\n term.emit('focus', {terminal: term});\n });\n};\n\n/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */\nTerminal.prototype.blur = function() {\n return this.textarea.blur();\n};\n\n/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */\nTerminal.bindBlur = function (term) {\n on(term.textarea, 'blur', function (ev) {\n term.refresh(term.y, term.y);\n if (term.sendFocus) {\n term.send(C0.ESC + '[O');\n }\n term.element.classList.remove('focus');\n term.clearCursorBlinkingInterval.apply(term);\n Terminal.focus = null;\n term.emit('blur', {terminal: term});\n });\n};\n\n/**\n * Initialize default behavior\n */\nTerminal.prototype.initGlobal = function() {\n var term = this;\n\n Terminal.bindKeys(this);\n Terminal.bindFocus(this);\n Terminal.bindBlur(this);\n\n // Bind clipboard functionality\n on(this.element, 'copy', function (ev) {\n copyHandler.call(this, ev, term);\n });\n on(this.textarea, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n on(this.element, 'paste', function (ev) {\n pasteHandler.call(this, ev, term);\n });\n\n function rightClickHandlerWrapper (ev) {\n rightClickHandler.call(this, ev, term);\n }\n\n if (term.browser.isFirefox) {\n on(this.element, 'mousedown', function (ev) {\n if (ev.button == 2) {\n rightClickHandlerWrapper(ev);\n }\n });\n } else {\n on(this.element, 'contextmenu', rightClickHandlerWrapper);\n }\n};\n\n/**\n * Apply key handling to the terminal\n */\nTerminal.bindKeys = function(term) {\n on(term.element, 'keydown', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyDown(ev);\n }, true);\n\n on(term.element, 'keypress', function(ev) {\n if (document.activeElement != this) {\n return;\n }\n term.keyPress(ev);\n }, true);\n\n on(term.element, 'keyup', function(ev) {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n term.focus(term);\n }\n }, true);\n\n on(term.textarea, 'keydown', function(ev) {\n term.keyDown(ev);\n }, true);\n\n on(term.textarea, 'keypress', function(ev) {\n term.keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.value = '';\n }, true);\n\n on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));\n on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));\n on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));\n term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));\n term.on('refresh', function (data) {\n term.queueLinkification(data.start, data.end)\n });\n};\n\n\n/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */\nTerminal.prototype.insertRow = function (row) {\n if (typeof row != 'object') {\n row = document.createElement('div');\n }\n\n this.rowContainer.appendChild(row);\n this.children.push(row);\n\n return row;\n};\n\n/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\nTerminal.prototype.open = function(parent) {\n var self=this, i=0, div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = this.document.getElementsByTagName('body')[0];\n\n //Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.add('xterm-theme-' + this.theme);\n this.setCursorBlinking(this.options.cursorBlink);\n\n this.element.style.height\n this.element.setAttribute('tabindex', 0);\n\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n this.element.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n // Create the container that will hold the lines of the terminal and then\n // produce the lines the lines.\n this.rowContainer = document.createElement('div');\n this.rowContainer.classList.add('xterm-rows');\n this.element.appendChild(this.rowContainer);\n this.children = [];\n this.linkifier.attachToDom(document, this.children);\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n // TODO: This should probably be inserted once it's filled to prevent an additional layout\n this.element.appendChild(this.helperContainer);\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', function() {\n self.emit('focus', {terminal: self});\n });\n this.textarea.addEventListener('blur', function() {\n self.emit('blur', {terminal: self});\n });\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n\n for (; i < this.rows; i++) {\n this.insertRow();\n }\n this.parent.appendChild(this.element);\n\n this.charMeasure = new CharMeasure(document, this.helperContainer);\n this.charMeasure.on('charsizechanged', function () {\n self.updateCharSizeCSS();\n });\n this.charMeasure.measure();\n\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.renderer = new Renderer(this);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that\n // need to be taken on the document.\n this.initGlobal();\n\n // Ensure there is a Terminal.focus.\n this.focus();\n\n on(this.element, 'click', function() {\n var selection = document.getSelection(),\n collapsed = selection.isCollapsed,\n isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';\n if (!isRange) {\n self.focus();\n }\n });\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n /**\n * This event is emitted when terminal has completed opening.\n *\n * @event open\n */\n this.emit('open');\n};\n\n\n/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */\nTerminal.loadAddon = function(addon, callback) {\n if (typeof exports === 'object' && typeof module === 'object') {\n // CommonJS\n return require('./addons/' + addon + '/' + addon);\n } else if (typeof define == 'function') {\n // RequireJS\n return require(['./addons/' + addon + '/' + addon], callback);\n } else {\n console.error('Cannot load a module without a CommonJS or RequireJS environment.');\n return false;\n }\n};\n\n/**\n * Updates the helper CSS class with any changes necessary after the terminal's\n * character width has been changed.\n */\nTerminal.prototype.updateCharSizeCSS = function() {\n this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}';\n}\n\n/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\nTerminal.prototype.bindMouse = function() {\n var el = this.element, self = this, pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev) {\n var button\n , pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = getCoords(ev);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev) {\n var button = pressed\n , pos;\n\n pos = getCoords(ev);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data, ch) {\n if (!self.utfMouse) {\n if (ch === 255) return data.push(0);\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) return data.push(0);\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button, pos) {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n var data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n + (pos.page || 0)\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n var data = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev) {\n var button\n , shift\n , meta\n , ctrl\n , mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch (ev.overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (self.browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = ev.wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n // mouse coordinates measured in cols/rows\n function getCoords(ev) {\n var x, y, w, h, el;\n\n // ignore browsers without pageX for now\n if (ev.pageX == null) return;\n\n x = ev.pageX;\n y = ev.pageY;\n el = self.element;\n\n // should probably check offsetParent\n // but this is more portable\n while (el && el !== self.document.documentElement) {\n x -= el.offsetLeft;\n y -= el.offsetTop;\n el = 'offsetParent' in el\n ? el.offsetParent\n : el.parentNode;\n }\n\n // convert to cols/rows\n x = Math.ceil(x / self.charMeasure.width);\n y = Math.ceil(y / self.charMeasure.height);\n\n // be sure to avoid sending\n // bad positions to the program\n if (x < 0) x = 0;\n if (x > self.cols) x = self.cols;\n if (y < 0) y = 0;\n if (y > self.rows) y = self.rows;\n\n // xterm sends raw bytes and\n // starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return {\n x: x,\n y: y,\n type: 'wheel'\n };\n }\n\n on(el, 'mousedown', function(ev) {\n if (!self.mouseEvents) return;\n\n // send the button\n sendButton(ev);\n\n // ensure focus\n self.focus();\n\n // fix for odd bug\n //if (self.vt200Mouse && !self.normalMouse) {\n if (self.vt200Mouse) {\n ev.overrideType = 'mouseup';\n sendButton(ev);\n return self.cancel(ev);\n }\n\n // bind events\n if (self.normalMouse) on(self.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!self.x10Mouse) {\n on(self.document, 'mouseup', function up(ev) {\n sendButton(ev);\n if (self.normalMouse) off(self.document, 'mousemove', sendMove);\n off(self.document, 'mouseup', up);\n return self.cancel(ev);\n });\n }\n\n return self.cancel(ev);\n });\n\n //if (self.normalMouse) {\n // on(self.document, 'mousemove', sendMove);\n //}\n\n on(el, 'wheel', function(ev) {\n if (!self.mouseEvents) return;\n if (self.x10Mouse\n || self.vt300Mouse\n || self.decLocator) return;\n sendButton(ev);\n return self.cancel(ev);\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', function(ev) {\n if (self.mouseEvents) return;\n self.viewport.onWheel(ev);\n return self.cancel(ev);\n });\n};\n\n/**\n * Destroys the terminal.\n */\nTerminal.prototype.destroy = function() {\n this.readable = false;\n this.writable = false;\n this._events = {};\n this.handler = function() {};\n this.write = function() {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n //this.emit('close');\n};\n\n/**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\nTerminal.prototype.refresh = function(start, end) {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n};\n\n/**\n * Queues linkification for the specified rows.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\nTerminal.prototype.queueLinkification = function(start, end) {\n if (this.linkifier) {\n for (let i = start; i <= end; i++) {\n this.linkifier.linkifyRow(i);\n }\n }\n}\n\n/**\n * Display the cursor element\n */\nTerminal.prototype.showCursor = function() {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.y, this.y);\n }\n};\n\n/**\n * Scroll the terminal down 1 row, creating a blank line.\n */\nTerminal.prototype.scroll = function() {\n var row;\n\n // Make room for the new row in lines\n if (this.lines.length === this.lines.maxLength) {\n this.lines.trimStart(1);\n this.ybase--;\n if (this.ydisp !== 0) {\n this.ydisp--;\n }\n }\n\n this.ybase++;\n\n // TODO: Why is this done twice?\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n\n // last line\n row = this.ybase + this.rows - 1;\n\n // subtract the bottom scroll region\n row -= this.rows - 1 - this.scrollBottom;\n\n if (row === this.lines.length) {\n // Optimization: pushing is faster than splicing when they amount to the same behavior\n this.lines.push(this.blankLine());\n } else {\n // add our new line\n this.lines.splice(row, 0, this.blankLine());\n }\n\n if (this.scrollTop !== 0) {\n if (this.ybase !== 0) {\n this.ybase--;\n if (!this.userScrolling) {\n this.ydisp = this.ybase;\n }\n }\n this.lines.splice(this.ybase + this.scrollTop, 1);\n }\n\n // this.maxRange();\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */\nTerminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {\n if (disp < 0) {\n this.userScrolling = true;\n } else if (disp + this.ydisp >= this.ybase) {\n this.userScrolling = false;\n }\n\n this.ydisp += disp;\n\n if (this.ydisp > this.ybase) {\n this.ydisp = this.ybase;\n } else if (this.ydisp < 0) {\n this.ydisp = 0;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n};\n\n/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\nTerminal.prototype.scrollPages = function(pageCount) {\n this.scrollDisp(pageCount * (this.rows - 1));\n}\n\n/**\n * Scrolls the display of the terminal to the top.\n */\nTerminal.prototype.scrollToTop = function() {\n this.scrollDisp(-this.ydisp);\n}\n\n/**\n * Scrolls the display of the terminal to the bottom.\n */\nTerminal.prototype.scrollToBottom = function() {\n this.scrollDisp(this.ybase - this.ydisp);\n}\n\n/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.write = function(data) {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n });\n }\n}\n\nTerminal.prototype.innerWrite = function() {\n var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n var data = writeBatch.shift();\n var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.y;\n this.refreshEnd = this.y;\n\n this.parser.parse(data);\n\n this.updateRange(this.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n var self = this;\n setTimeout(function () {\n self.innerWrite();\n }, 0);\n } else {\n this.writeInProgress = false;\n }\n};\n\n/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */\nTerminal.prototype.writeln = function(data) {\n this.write(data + '\\r\\n');\n};\n\n/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n * the default action. The function returns whether the event should be processed by xterm.js.\n */\nTerminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {\n this.customKeydownHandler = customKeydownHandler;\n}\n\n/**\n * Attaches a http(s) link handler, forcing web links to behave differently to\n * regular tags. This will trigger a refresh as links potentially need to be\n * reconstructed. Calling this with null will remove the handler.\n * @param {LinkHandler} handler The handler callback function.\n */\nTerminal.prototype.setHypertextLinkHandler = function(handler) {\n if (!this.linkifier) {\n throw new Error('Cannot attach a hypertext link handler before Terminal.open is called');\n }\n this.linkifier.setHypertextLinkHandler(handler);\n // Refresh to force links to refresh\n this.refresh(0, this.rows - 1);\n}\n\n/**\n * Attaches a validation callback for hypertext links. This is useful to use\n * validation logic or to do something with the link's element and url.\n * @param {LinkMatcherValidationCallback} callback The callback to use, this can\n * be cleared with null.\n */\nTerminal.prototype.setHypertextValidationCallback = function(handler) {\n if (!this.linkifier) {\n throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called');\n }\n this.linkifier.setHypertextValidationCallback(handler);\n // Refresh to force links to refresh\n this.refresh(0, this.rows - 1);\n}\n\n/**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param {RegExp} regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param {LinkHandler} handler The callback when the link is called.\n * @param {LinkMatcherOptions} [options] Options for the link matcher.\n * @return {number} The ID of the new matcher, this can be used to deregister.\n */\nTerminal.prototype.registerLinkMatcher = function(regex, handler, options) {\n if (this.linkifier) {\n var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);\n this.refresh(0, this.rows - 1);\n return matcherId;\n }\n}\n\n/**\n * Deregisters a link matcher if it has been registered.\n * @param {number} matcherId The link matcher's ID (returned after register)\n */\nTerminal.prototype.deregisterLinkMatcher = function(matcherId) {\n if (this.linkifier) {\n if (this.linkifier.deregisterLinkMatcher(matcherId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n}\n\n/**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\nTerminal.prototype.keyDown = function(ev) {\n if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {\n return false;\n }\n\n this.restartCursorBlinking();\n\n if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n var self = this;\n var result = this.evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollDisp) {\n this.scrollDisp(result.scrollDisp);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n};\n\n/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */\nTerminal.prototype.evaluateKeyEscapeSequence = function(ev) {\n var result = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollDisp: undefined\n };\n var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;\n switch (ev.keyCode) {\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key == C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key == C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollDisp = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollDisp = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n }\n break;\n }\n\n return result;\n};\n\n/**\n * Set the G level of the terminal\n * @param g\n */\nTerminal.prototype.setgLevel = function(g) {\n this.glevel = g;\n this.charset = this.charsets[g];\n};\n\n/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\nTerminal.prototype.setgCharset = function(g, charset) {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n};\n\n/**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\nTerminal.prototype.keyPress = function(ev) {\n var key;\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return false;\n};\n\n/**\n * Send data for handling to the terminal\n * @param {string} data\n */\nTerminal.prototype.send = function(data) {\n var self = this;\n\n if (!this.queue) {\n setTimeout(function() {\n self.handler(self.queue);\n self.queue = '';\n }, 1);\n }\n\n this.queue += data;\n};\n\n/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\nTerminal.prototype.bell = function() {\n if (!this.visualBell) return;\n var self = this;\n this.element.style.borderColor = 'white';\n setTimeout(function() {\n self.element.style.borderColor = '';\n }, 10);\n if (this.popOnBell) this.focus();\n};\n\n/**\n * Log the current state to the console.\n */\nTerminal.prototype.log = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.log.apply(this.context.console, args);\n};\n\n/**\n * Log the current state as error to the console.\n */\nTerminal.prototype.error = function() {\n if (!this.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n var args = Array.prototype.slice.call(arguments);\n this.context.console.error.apply(this.context.console, args);\n};\n\n/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\nTerminal.prototype.resize = function(x, y) {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n var line\n , el\n , i\n , j\n , ch\n , addToY;\n\n if (x === this.cols && y === this.rows) {\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n // resize cols\n j = this.cols;\n if (j < x) {\n ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?\n i = this.lines.length;\n while (i--) {\n while (this.lines.get(i).length < x) {\n this.lines.get(i).push(ch);\n }\n }\n }\n\n this.cols = x;\n this.setupStops(this.cols);\n\n // resize rows\n j = this.rows;\n addToY = 0;\n if (j < y) {\n el = this.element;\n while (j++ < y) {\n // y is rows, not this.y\n if (this.lines.length < y + this.ybase) {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(this.blankLine());\n }\n }\n if (this.children.length < y) {\n this.insertRow();\n }\n }\n } else { // (j > y)\n while (j-- > y) {\n if (this.lines.length > y + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n if (this.children.length > y) {\n el = this.children.shift();\n if (!el) continue;\n el.parentNode.removeChild(el);\n }\n }\n }\n this.rows = y;\n\n // Make sure that the cursor stays on screen\n if (this.y >= y) {\n this.y = y - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= x) {\n this.x = x - 1;\n }\n\n this.scrollTop = 0;\n this.scrollBottom = y - 1;\n\n this.charMeasure.measure();\n\n this.refresh(0, this.rows - 1);\n\n this.normal = null;\n\n this.geometry = [this.cols, this.rows];\n this.emit('resize', {terminal: this, cols: x, rows: y});\n};\n\n/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\nTerminal.prototype.updateRange = function(y) {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n};\n\n/**\n * Set the range of refreshing to the maximum value\n */\nTerminal.prototype.maxRange = function() {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n};\n\n\n\n/**\n * Setup the tab stops.\n * @param {number} i\n */\nTerminal.prototype.setupStops = function(i) {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this.cols; i += this.getOption('tabStopWidth')) {\n this.tabs[i] = true;\n }\n};\n\n\n/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */\nTerminal.prototype.prevStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */\nTerminal.prototype.nextStop = function(x) {\n if (x == null) x = this.x;\n while (!this.tabs[++x] && x < this.cols);\n return x >= this.cols\n ? this.cols - 1\n : x < 0 ? 0 : x;\n};\n\n\n/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseRight = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n\n\n/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\nTerminal.prototype.eraseLeft = function(x, y) {\n var line = this.lines.get(this.ybase + y);\n if (!line) {\n return;\n }\n var ch = [this.eraseAttr(), ' ', 1]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n};\n\n/**\n * Clears the entire buffer, making the prompt line the new first line.\n */\nTerminal.prototype.clear = function() {\n if (this.ybase === 0 && this.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.lines.set(0, this.lines.get(this.ybase + this.y));\n this.lines.length = 1;\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n for (var i = 1; i < this.rows; i++) {\n this.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.ydisp);\n};\n\n/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\nTerminal.prototype.eraseLine = function(y) {\n this.eraseRight(0, y);\n};\n\n\n/**\n * Return the data array of a blank line\n * @param {number} cur First bunch of data for each \"blank\" character.\n */\nTerminal.prototype.blankLine = function(cur) {\n var attr = cur\n ? this.eraseAttr()\n : this.defAttr;\n\n var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character\n , line = []\n , i = 0;\n\n for (; i < this.cols; i++) {\n line[i] = ch;\n }\n\n return line;\n};\n\n\n/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */\nTerminal.prototype.ch = function(cur) {\n return cur\n ? [this.eraseAttr(), ' ', 1]\n : [this.defAttr, ' ', 1];\n};\n\n\n/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */\nTerminal.prototype.is = function(term) {\n var name = this.termName;\n return (name + '').indexOf(term) === 0;\n};\n\n\n/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\nTerminal.prototype.handler = function(data) {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.ybase !== this.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n};\n\n\n/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\nTerminal.prototype.handleTitle = function(title) {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n};\n\n\n/**\n * ESC\n */\n\n/**\n * ESC D Index (IND is 0x84).\n */\nTerminal.prototype.index = function() {\n this.y++;\n if (this.y > this.scrollBottom) {\n this.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.x >= this.cols) {\n this.x--;\n }\n};\n\n\n/**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\nTerminal.prototype.reverseIndex = function() {\n var j;\n if (this.y === this.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);\n this.lines.set(this.y + this.ybase, this.blankLine(true));\n this.updateRange(this.scrollTop);\n this.updateRange(this.scrollBottom);\n } else {\n this.y--;\n }\n};\n\n\n/**\n * ESC c Full Reset (RIS).\n */\nTerminal.prototype.reset = function() {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n var customKeydownHandler = this.customKeydownHandler;\n Terminal.call(this, this.options);\n this.customKeydownHandler = customKeydownHandler;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n};\n\n\n/**\n * ESC H Tab Set (HTS is 0x88).\n */\nTerminal.prototype.tabSet = function() {\n this.tabs[this.x] = true;\n};\n\n/**\n * Helpers\n */\n\nfunction on(el, type, handler, capture) {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach(function (element) {\n element.addEventListener(type, handler, capture || false);\n });\n}\n\nfunction off(el, type, handler, capture) {\n el.removeEventListener(type, handler, capture || false);\n}\n\nfunction cancel(ev, force) {\n if (!this.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n}\n\nfunction inherits(child, parent) {\n function f() {\n this.constructor = child;\n }\n f.prototype = parent.prototype;\n child.prototype = new f;\n}\n\nfunction indexOf(obj, el) {\n var i = obj.length;\n while (i--) {\n if (obj[i] === el) return i;\n }\n return -1;\n}\n\nfunction isThirdLevelShift(term, ev) {\n var thirdLevelKey =\n (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type == 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\n// Expose to InputHandler (temporary)\nTerminal.prototype.matchColor = matchColor;\n\nfunction matchColor(r1, g1, b1) {\n var hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColor._cache[hash] != null) {\n return matchColor._cache[hash];\n }\n\n var ldiff = Infinity\n , li = -1\n , i = 0\n , c\n , r2\n , g2\n , b2\n , diff;\n\n for (; i < Terminal.vcolors.length; i++) {\n c = Terminal.vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColor.distance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColor._cache[hash] = li;\n}\n\nmatchColor._cache = {};\n\n// http://stackoverflow.com/questions/1633828\nmatchColor.distance = function(r1, g1, b1, r2, g2, b2) {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\nfunction each(obj, iter, con) {\n if (obj.forEach) return obj.forEach(iter, con);\n for (var i = 0; i < obj.length; i++) {\n iter.call(con, obj[i], i, obj);\n }\n}\n\nfunction wasMondifierKeyOnlyEvent(ev) {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\nfunction keys(obj) {\n if (Object.keys) return Object.keys(obj);\n var key, keys = [];\n for (key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n keys.push(key);\n }\n }\n return keys;\n}\n\n/**\n * Expose\n */\n\nTerminal.EventEmitter = EventEmitter;\nTerminal.inherits = inherits;\n\n/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */\nTerminal.on = on;\nTerminal.off = off;\nTerminal.cancel = cancel;\n\nmodule.exports = Terminal;\n","/**\n * Generic utilities module with methods that can be helpful at different parts of the code base.\n * @module xterm/utils/Generic\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any) {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n * @module xterm/utils/CircularList\n * @license MIT\n */\nexport class CircularList {\n private _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(maxLength: number) {\n this._array = new Array(maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._array.length;\n }\n\n public set maxLength(newMaxLength: number) {\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number, array: T[]) => void) => void {\n return this._array.forEach;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this.maxLength) {\n this._startIndex++;\n if (this._startIndex === this.maxLength) {\n this._startIndex = 0;\n }\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n if (items && items.length) {\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n if (this._length + items.length > this.maxLength) {\n this._startIndex += (this._length + items.length) - this.maxLength;\n this._length = this.maxLength;\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * @module xterm/utils/CharMeasure\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter.js';\n\n/**\n * Utility class that measures the size of a character.\n */\nexport class CharMeasure extends EventEmitter {\n private _document: Document;\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(document: Document, parentElement: HTMLElement) {\n super();\n this._document = document;\n this._parentElement = parentElement;\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(): void {\n if (!this._measureElement) {\n this._measureElement = this._document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.textContent = 'W';\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._parentElement.appendChild(this._measureElement);\n // Perform _doMeasure async if the element was just attached as sometimes\n // getBoundingClientRect does not return accurate values without this.\n setTimeout(() => this._doMeasure(), 0);\n } else {\n this._doMeasure();\n }\n }\n\n private _doMeasure(): void {\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = geometry.height;\n this.emit('charsizechanged');\n }\n }\n}\n","/**\n * Attributes and methods to help with identifying the current browser and platform.\n * @module xterm/utils/Browser\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n","/**\n * Clipboard handler module: exports methods for handling all clipboard-related events in the\n * terminal.\n * @module xterm/handlers/Clipboard\n * @license MIT\n */\n\nimport { ITerminal } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string);\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n * 1. stripping all trailing white spaces\n * 2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nexport function prepareTextForClipboard(text: string): string {\n let space = String.fromCharCode(32),\n nonBreakingSpace = String.fromCharCode(160),\n allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n processedText = text.split('\\n').map(function (line) {\n // Strip all trailing white spaces and convert all non-breaking spaces\n // to regular spaces.\n let processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n return processedLine;\n }).join('\\n');\n\n return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal) {\n // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`\n // property that we use below for Internet Explorer.\n let copiedText = window.getSelection().toString(),\n text = prepareTextForClipboard(copiedText);\n\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', text);\n } else {\n ev.clipboardData.setData('text/plain', text);\n }\n\n ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal) {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text) {\n term.handler(text);\n term.textarea.value = '';\n return term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {MouseEvent} ev The original right click event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal) {\n let s = document.getSelection(),\n selectedText = prepareTextForClipboard(s.toString()),\n clickIsOnSelection = false,\n x = ev.clientX,\n y = ev.clientY;\n\n if (s.rangeCount) {\n let r = s.getRangeAt(0),\n cr = r.getClientRects();\n\n for (let i = 0; i < cr.length; i++) {\n let rect = cr[i];\n\n clickIsOnSelection = (\n (x > rect.left) && (x < rect.right) &&\n (y > rect.top) && (y < rect.bottom)\n );\n\n if (clickIsOnSelection) {\n break;\n }\n }\n // If we clicked on selection and selection is not a single space,\n // then mark the right click as copy-only. We check for the single\n // space selection, as this can happen when clicking on an  \n // and there is not much pointing in copying a single space.\n if (selectedText.match(/^\\s$/) || !selectedText.length) {\n clickIsOnSelection = false;\n }\n }\n\n // Bring textarea at the cursor position\n if (!clickIsOnSelection) {\n term.textarea.style.position = 'fixed';\n term.textarea.style.width = '20px';\n term.textarea.style.height = '20px';\n term.textarea.style.left = (x - 10) + 'px';\n term.textarea.style.top = (y - 10) + 'px';\n term.textarea.style.zIndex = '1000';\n term.textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(function () {\n term.textarea.style.position = null;\n term.textarea.style.width = null;\n term.textarea.style.height = null;\n term.textarea.style.left = null;\n term.textarea.style.top = null;\n term.textarea.style.zIndex = null;\n }, 4);\n }\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport {\n private currentRowHeight: number;\n private lastRecordedBufferLength: number;\n private lastRecordedViewportHeight: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasureElement A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.currentRowHeight = 0;\n this.lastRecordedBufferLength = 0;\n this.lastRecordedViewportHeight = 0;\n\n this.terminal.on('scroll', this.syncScrollArea.bind(this));\n this.terminal.on('resize', this.syncScrollArea.bind(this));\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n // Perform this async to ensure the CharMeasure is ready.\n setTimeout(() => this.syncScrollArea(), 0);\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param charSize A character size measurement bounding rect object, if it doesn't exist it will\n * be created.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;\n if (rowHeightChanged) {\n this.currentRowHeight = this.charMeasure.height;\n this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';\n this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';\n }\n const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n if (rowHeightChanged || viewportHeightChanged) {\n this.lastRecordedViewportHeight = this.terminal.rows;\n this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';\n }\n this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.charMeasure.height !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event) {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.ydisp;\n this.terminal.scrollDisp(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent) {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n}\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * The maximum number of refresh frames to skip when the write buffer is non-\n * empty. Note that these frames may be intermingled with frames that are\n * skipped via requestAnimationFrame's mechanism.\n */\nconst MAX_REFRESH_FRAME_SKIP = 5;\n\n/**\n * Flags used to render terminal text properly.\n */\nenum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16\n};\n\nlet brokenBold: boolean = null;\n\nexport class Renderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshFramesSkipped = 0;\n private _refreshAnimationFrame = null;\n\n constructor(private _terminal: ITerminal) {\n // Figure out whether boldness affects\n // the character width of monospace fonts.\n if (brokenBold === null) {\n brokenBold = checkBoldBroken((this._terminal).element);\n }\n\n // TODO: Pull more DOM interactions into Renderer.constructor, element for\n // example should be owned by Renderer (and also exposed by Terminal due to\n // to established public API).\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n // Skip MAX_REFRESH_FRAME_SKIP frames if the writeBuffer is non-empty as it\n // will need to be immediately refreshed anyway. This saves a lot of\n // rendering time as the viewport DOM does not need to be refreshed, no\n // scroll events, no layouts, etc.\n const skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;\n if (skipFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n return;\n }\n\n this._refreshFramesSkipped = 0;\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n this._refresh(start, end);\n }\n\n /**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n * - First value: a utf-16 character.\n * - Second value:\n * - Next 9 bits: background color (0-511).\n * - Next 9 bits: foreground color (0-511).\n * - Next 14 bits: a mask for misc. flags:\n * - 1=bold\n * - 2=underline\n * - 4=blink\n * - 8=inverse\n * - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n */\n private _refresh(start: number, end: number): void {\n let x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;\n\n // If this is a big refresh, remove the terminal rows from the DOM for faster calculations\n if (end - start >= this._terminal.rows / 2) {\n parent = this._terminal.element.parentNode;\n if (parent) {\n this._terminal.element.removeChild(this._terminal.rowContainer);\n }\n }\n\n width = this._terminal.cols;\n y = start;\n\n if (end >= this._terminal.rows) {\n this._terminal.log('`end` is too large. Most likely a bad CSR.');\n end = this._terminal.rows - 1;\n }\n\n for (; y <= end; y++) {\n row = y + this._terminal.ydisp;\n\n line = this._terminal.lines.get(row);\n if (!line || !this._terminal.children[y]) {\n // Continue if the line is not available, this means a resize is currently in progress\n continue;\n }\n out = '';\n\n if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp)\n && this._terminal.cursorState\n && !this._terminal.cursorHidden) {\n x = this._terminal.x;\n } else {\n x = -1;\n }\n\n attr = this._terminal.defAttr;\n i = 0;\n\n for (; i < width; i++) {\n if (!line[i]) {\n // Continue if the character is not available, this means a resize is currently in progress\n continue;\n }\n data = line[i][0];\n ch = line[i][1];\n ch_width = line[i][2];\n if (!ch_width)\n continue;\n\n if (i === x) data = -1;\n\n if (data !== attr) {\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n if (data !== this._terminal.defAttr) {\n if (data === -1) {\n out += '';\n } else {\n let classNames = [];\n\n bg = data & 0x1ff;\n fg = (data >> 9) & 0x1ff;\n flags = data >> 18;\n\n if (flags & FLAGS.BOLD) {\n if (!brokenBold) {\n classNames.push('xterm-bold');\n }\n // See: XTerm*boldColors\n if (fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.UNDERLINE) {\n classNames.push('xterm-underline');\n }\n\n if (flags & FLAGS.BLINK) {\n classNames.push('xterm-blink');\n }\n\n // If inverse flag is on, then swap the foreground and background variables.\n if (flags & FLAGS.INVERSE) {\n /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */\n bg = [fg, fg = bg][0];\n // Should inverse just be before the\n // above boldColors effect instead?\n if ((flags & 1) && fg < 8) fg += 8;\n }\n\n if (flags & FLAGS.INVISIBLE) {\n classNames.push('xterm-hidden');\n }\n\n /**\n * Weird situation: Invert flag used black foreground and white background results\n * in invalid background color, positioned at the 256 index of the 256 terminal\n * color map. Pin the colors manually in such a case.\n *\n * Source: https://github.com/sourcelair/xterm.js/issues/57\n */\n if (flags & FLAGS.INVERSE) {\n if (bg === 257) {\n bg = 15;\n }\n if (fg === 256) {\n fg = 0;\n }\n }\n\n if (bg < 256) {\n classNames.push('xterm-bg-color-' + bg);\n }\n\n if (fg < 256) {\n classNames.push('xterm-color-' + fg);\n }\n\n out += '':\n out += '>';\n break;\n default:\n if (ch <= ' ') {\n out += ' ';\n } else {\n out += ch;\n }\n break;\n }\n if (ch_width === 2) {\n out += '';\n }\n\n attr = data;\n }\n\n if (attr !== this._terminal.defAttr) {\n out += '';\n }\n\n this._terminal.children[y].innerHTML = out;\n }\n\n if (parent) {\n this._terminal.element.appendChild(this._terminal.rowContainer);\n }\n\n this._terminal.emit('refresh', {element: this._terminal.element, start: start, end: end});\n };\n}\n\n\n// if bold is broken, we can't\n// use it in the terminal.\nfunction checkBoldBroken(terminal) {\n const document = terminal.ownerDocument;\n const el = document.createElement('span');\n el.innerHTML = 'hello world';\n terminal.appendChild(el);\n const w1 = el.offsetWidth;\n const h1 = el.offsetHeight;\n el.style.fontWeight = 'bold';\n const w2 = el.offsetWidth;\n const h2 = el.offsetHeight;\n terminal.removeChild(el);\n return w1 !== w2 || h1 !== h2;\n}\n","/**\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nenum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string) {\n let l = data.length, j, cs, ch, code, low;\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n let pt = this._terminal.currentParam\n , valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.scrollTop + 1)\n + ';'\n + (this._terminal.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n // TODO: Don't declare pt twice\n /*let*/ pt = this._terminal.currentParam\n , valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number) {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * @license MIT\n */\n\nimport { LinkMatcherOptions } from './Interfaces';\nimport { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types';\n\nconst INVALID_LINK_CLASS = 'xterm-invalid-link';\n\nconst protocolClause = '(https?:\\\\/\\\\/)';\nconst domainCharacterSet = '[\\\\da-z\\\\.-]+';\nconst negatedDomainCharacterSet = '[^\\\\da-z\\\\.-]+';\nconst domainBodyClause = '(' + domainCharacterSet + ')';\nconst tldClause = '([a-z\\\\.]{2,6})';\nconst ipClause = '((\\\\d{1,3}\\\\.){3}\\\\d{1,3})';\nconst localHostClause = '(localhost)';\nconst portClause = '(:\\\\d{1,5})';\nconst hostClause = '((' + domainBodyClause + '\\\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';\nconst pathClause = '(\\\\/[\\\\/\\\\w\\\\.\\\\-%~]*)*';\nconst queryStringHashFragmentCharacterSet = '[0-9\\\\w\\\\[\\\\]\\\\(\\\\)\\\\/\\\\?\\\\!#@$%&\\'*+,:;~\\\\=\\\\.\\\\-]*';\nconst queryStringClause = '(\\\\?' + queryStringHashFragmentCharacterSet + ')?';\nconst hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';\nconst negatedPathCharacterSet = '[^\\\\/\\\\w\\\\.\\\\-%]+';\nconst bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause;\nconst start = '(?:^|' + negatedDomainCharacterSet + ')(';\nconst end = ')($|' + negatedPathCharacterSet + ')';\nconst strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end);\n\n/**\n * The ID of the built in http(s) link matcher.\n */\nconst HYPERTEXT_LINK_MATCHER_ID = 0;\n\n/**\n * The Linkifier applies links to rows shortly after they have been refreshed.\n */\nexport class Linkifier {\n /**\n * The time to wait after a row is changed before it is linkified. This prevents\n * the costly operation of searching every row multiple times, potentially a\n * huge amount of times.\n */\n protected static TIME_BEFORE_LINKIFY = 200;\n\n protected _linkMatchers: LinkMatcher[];\n\n private _document: Document;\n private _rows: HTMLElement[];\n private _rowTimeoutIds: number[];\n private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;\n\n constructor() {\n this._rowTimeoutIds = [];\n this._linkMatchers = [];\n this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });\n }\n\n /**\n * Attaches the linkifier to the DOM, enabling linkification.\n * @param document The document object.\n * @param rows The array of rows to apply links to.\n */\n public attachToDom(document: Document, rows: HTMLElement[]) {\n this._document = document;\n this._rows = rows;\n }\n\n /**\n * Queues a row for linkification.\n * @param {number} rowIndex The index of the row to linkify.\n */\n public linkifyRow(rowIndex: number): void {\n // Don't attempt linkify if not yet attached to DOM\n if (!this._document) {\n return;\n }\n\n const timeoutId = this._rowTimeoutIds[rowIndex];\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), Linkifier.TIME_BEFORE_LINKIFY);\n }\n\n /**\n * Attaches a handler for hypertext links, overriding default behavior\n * for standard http(s) links.\n * @param {LinkHandler} handler The handler to use, this can be cleared with\n * null.\n */\n public setHypertextLinkHandler(handler: LinkMatcherHandler): void {\n this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler;\n }\n\n /**\n * Attaches a validation callback for hypertext links.\n * @param {LinkMatcherValidationCallback} callback The callback to use, this\n * can be cleared with null.\n */\n public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void {\n this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback;\n }\n\n /**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param {RegExp} regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param {LinkHandler} handler The callback when the link is called.\n * @param {LinkMatcherOptions} [options] Options for the link matcher.\n * @return {number} The ID of the new matcher, this can be used to deregister.\n */\n public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: LinkMatcherOptions = {}): number {\n if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) {\n throw new Error('handler must be defined');\n }\n const matcher: LinkMatcher = {\n id: this._nextLinkMatcherId++,\n regex,\n handler,\n matchIndex: options.matchIndex,\n validationCallback: options.validationCallback,\n priority: options.priority || 0\n };\n this._addLinkMatcherToList(matcher);\n return matcher.id;\n }\n\n /**\n * Inserts a link matcher to the list in the correct position based on the\n * priority of each link matcher. New link matchers of equal priority are\n * considered after older link matchers.\n * @param matcher The link matcher to be added.\n */\n private _addLinkMatcherToList(matcher: LinkMatcher): void {\n if (this._linkMatchers.length === 0) {\n this._linkMatchers.push(matcher);\n return;\n }\n\n for (let i = this._linkMatchers.length - 1; i >= 0; i--) {\n if (matcher.priority <= this._linkMatchers[i].priority) {\n this._linkMatchers.splice(i + 1, 0, matcher);\n return;\n }\n }\n\n this._linkMatchers.splice(0, 0, matcher);\n }\n\n /**\n * Deregisters a link matcher if it has been registered.\n * @param {number} matcherId The link matcher's ID (returned after register)\n * @return {boolean} Whether a link matcher was found and deregistered.\n */\n public deregisterLinkMatcher(matcherId: number): boolean {\n // ID 0 is the hypertext link matcher which cannot be deregistered\n for (let i = 1; i < this._linkMatchers.length; i++) {\n if (this._linkMatchers[i].id === matcherId) {\n this._linkMatchers.splice(i, 1);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Linkifies a row.\n * @param {number} rowIndex The index of the row to linkify.\n */\n private _linkifyRow(rowIndex: number): void {\n const row = this._rows[rowIndex];\n if (!row) {\n return;\n }\n const text = row.textContent;\n for (let i = 0; i < this._linkMatchers.length; i++) {\n const matcher = this._linkMatchers[i];\n const linkElements = this._doLinkifyRow(row, matcher);\n if (linkElements.length > 0) {\n // Fire validation callback\n if (matcher.validationCallback) {\n for (let j = 0; j < linkElements.length; j++) {\n const element = linkElements[j];\n matcher.validationCallback(element.textContent, element, isValid => {\n if (!isValid) {\n element.classList.add(INVALID_LINK_CLASS);\n }\n });\n }\n }\n // Only allow a single LinkMatcher to trigger on any given row.\n return;\n }\n }\n }\n\n /**\n * Linkifies a row given a specific handler.\n * @param {HTMLElement} row The row to linkify.\n * @param {LinkMatcher} matcher The link matcher for this line.\n * @return The link element if it was added, otherwise undefined.\n */\n private _doLinkifyRow(row: HTMLElement, matcher: LinkMatcher): HTMLElement[] {\n // Iterate over nodes as we want to consider text nodes\n let result = [];\n const isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID;\n const nodes = row.childNodes;\n\n // Find the first match\n let match = row.textContent.match(matcher.regex);\n if (!match || match.length === 0) {\n return result;\n }\n let uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];\n // Set the next searches start index\n let rowStartIndex = match.index + uri.length;\n\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const searchIndex = node.textContent.indexOf(uri);\n if (searchIndex >= 0) {\n const linkElement = this._createAnchorElement(uri, matcher.handler, isHttpLinkMatcher);\n if (node.textContent.length === uri.length) {\n // Matches entire string\n if (node.nodeType === 3 /*Node.TEXT_NODE*/) {\n this._replaceNode(node, linkElement);\n } else {\n const element = (node);\n if (element.nodeName === 'A') {\n // This row has already been linkified\n return result;\n }\n element.innerHTML = '';\n element.appendChild(linkElement);\n }\n } else {\n // Matches part of string\n const nodesAdded = this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex);\n // No need to consider the new nodes\n i += nodesAdded;\n }\n result.push(linkElement);\n\n // Find the next match\n match = row.textContent.substring(rowStartIndex).match(matcher.regex);\n if (!match || match.length === 0) {\n return result;\n }\n uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];\n rowStartIndex += match.index + uri.length;\n }\n }\n return result;\n }\n\n /**\n * Creates a link anchor element.\n * @param {string} uri The uri of the link.\n * @return {HTMLAnchorElement} The link.\n */\n private _createAnchorElement(uri: string, handler: LinkMatcherHandler, isHypertextLinkHandler: boolean): HTMLAnchorElement {\n const element = this._document.createElement('a');\n element.textContent = uri;\n element.draggable = false;\n if (isHypertextLinkHandler) {\n element.href = uri;\n // Force link on another tab so work is not lost\n element.target = '_blank';\n element.addEventListener('click', (event: MouseEvent) => {\n if (handler) {\n return handler(event, uri);\n }\n });\n } else {\n element.addEventListener('click', (event: MouseEvent) => {\n // Don't execute the handler if the link is flagged as invalid\n if (element.classList.contains(INVALID_LINK_CLASS)) {\n return;\n }\n return handler(event, uri);\n });\n }\n return element;\n }\n\n /**\n * Replace a node with 1 or more other nodes.\n * @param {Node} oldNode The node to replace.\n * @param {Node[]} newNodes The new nodes to insert in order.\n */\n private _replaceNode(oldNode: Node, ...newNodes: Node[]): void {\n const parent = oldNode.parentNode;\n for (let i = 0; i < newNodes.length; i++) {\n parent.insertBefore(newNodes[i], oldNode);\n }\n parent.removeChild(oldNode);\n }\n\n /**\n * Replace a substring within a node with a new node.\n * @param {Node} targetNode The target node; either a text node or a \n * containing a single text node.\n * @param {Node} newNode The new node to insert.\n * @param {string} substring The substring to replace.\n * @param {number} substringIndex The index of the substring within the string.\n * @return The number of nodes to skip when searching for the next uri.\n */\n private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): number {\n let node = targetNode;\n if (node.nodeType !== 3/*Node.TEXT_NODE*/) {\n node = node.childNodes[0];\n }\n\n // The targetNode will be either a text node or a . The text node\n // (targetNode or its only-child) needs to be replaced with newNode plus new\n // text nodes potentially on either side.\n if (node.childNodes.length === 0 && node.nodeType !== 3/*Node.TEXT_NODE*/) {\n throw new Error('targetNode must be a text node or only contain a single text node');\n }\n\n const fullText = node.textContent;\n\n if (substringIndex === 0) {\n // Replace with \n const rightText = fullText.substring(substring.length);\n const rightTextNode = this._document.createTextNode(rightText);\n this._replaceNode(node, newNode, rightTextNode);\n return 0;\n }\n\n if (substringIndex === targetNode.textContent.length - substring.length) {\n // Replace with \n const leftText = fullText.substring(0, substringIndex);\n const leftTextNode = this._document.createTextNode(leftText);\n this._replaceNode(node, leftTextNode, newNode);\n return 0;\n }\n\n // Replace with \n const leftText = fullText.substring(0, substringIndex);\n const leftTextNode = this._document.createTextNode(leftText);\n const rightText = fullText.substring(substringIndex + substring.length);\n const rightTextNode = this._document.createTextNode(rightText);\n this._replaceNode(node, leftTextNode, newNode, rightTextNode);\n return 1;\n }\n}\n","/**\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n // TODO: We want to type _terminal when it's pulled into TS\n constructor(private _terminal: any) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.y + this._terminal.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.x) {\n // dont overflow left\n if (this._terminal.lines.get(row)[this._terminal.x - 1]) {\n if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {\n\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.lines.get(row)[this._terminal.x - 2])\n this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;\n\n } else {\n this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;\n }\n this._terminal.updateRange(this._terminal.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.x = 0;\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.y + this._terminal.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();\n if (removed[2] === 0\n && this._terminal.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)\n this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];\n\n // insert empty cell at cursor\n this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);\n }\n }\n\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];\n this._terminal.x++;\n this._terminal.updateRange(this._terminal.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];\n this._terminal.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n if (!this._terminal.visualBell) {\n return;\n }\n this._terminal.element.style.borderColor = 'white';\n setTimeout(() => this._terminal.element.style.borderColor = '', 10);\n if (this._terminal.popOnBell) {\n this._terminal.focus();\n }\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.x = 0;\n }\n this._terminal.y++;\n if (this._terminal.y > this._terminal.scrollBottom) {\n this._terminal.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.x > 0) {\n this._terminal.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.x = this._terminal.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) param = 1;\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row).splice(j++, 0, ch);\n this._terminal.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]) {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n this._terminal.x -= param;\n if (this._terminal.x < 0) {\n this._terminal.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y -= param;\n if (this._terminal.y < 0) {\n this._terminal.y = 0;\n }\n this._terminal.x = 0;\n };\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let row, col;\n\n row = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.x = col;\n this._terminal.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n j = this._terminal.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n j = this._terminal.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._terminal.lines.length - this._terminal.rows;\n if (scrollBackSize > 0) {\n this._terminal.lines.trimStart(scrollBackSize);\n this._terminal.ybase = Math.max(this._terminal.ybase - scrollBackSize, 0);\n this._terminal.ydisp = Math.max(this._terminal.ydisp - scrollBackSize, 0);\n }\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.x, this._terminal.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.x, this._terminal.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase--;\n this._terminal.ydisp--;\n row--;\n j--;\n }\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(j, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param, row, j;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n row = this._terminal.y + this._terminal.ybase;\n\n j = this._terminal.rows - 1 - this._terminal.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.ybase - j;\n\n while (param--) {\n if (this._terminal.lines.length === this._terminal.lines.maxLength) {\n // Trim the start of lines to make room for the new line\n this._terminal.lines.trimStart(1);\n this._terminal.ybase -= 1;\n this._terminal.ydisp -= 1;\n }\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));\n this._terminal.lines.splice(row, 1);\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.y);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param, row, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param--) {\n this._terminal.lines.get(row).splice(this._terminal.x, 1);\n this._terminal.lines.get(row).push(ch);\n }\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);\n this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.scrollTop);\n this._terminal.updateRange(this._terminal.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param, row, j, ch;\n\n param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n row = this._terminal.y + this._terminal.ybase;\n j = this._terminal.x;\n ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.x = this._terminal.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x = param - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.x += param;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1\n , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)\n , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];\n\n while (param--) {\n line[this._terminal.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y = param - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.y += param;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.y = params[0] - 1;\n if (this._terminal.y >= this._terminal.rows) {\n this._terminal.y = this._terminal.rows - 1;\n }\n\n this._terminal.x = params[1] - 1;\n if (this._terminal.x >= this._terminal.cols) {\n this._terminal.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.tabs[this._terminal.x];\n } else if (param === 3) {\n this._terminal.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._terminal.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.style.cursor = 'default';\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[ Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._terminal.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.style.cursor = '';\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n ; // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n if (this._terminal.normal) {\n this._terminal.lines = this._terminal.normal.lines;\n this._terminal.ybase = this._terminal.normal.ybase;\n this._terminal.ydisp = this._terminal.normal.ydisp;\n this._terminal.x = this._terminal.normal.x;\n this._terminal.y = this._terminal.normal.y;\n this._terminal.scrollTop = this._terminal.normal.scrollTop;\n this._terminal.scrollBottom = this._terminal.normal.scrollBottom;\n this._terminal.tabs = this._terminal.normal.tabs;\n this._terminal.normal = null;\n // if (params === 1049) {\n // this.x = this.savedX;\n // this.y = this.savedY;\n // }\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n }\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n let l = params.length\n , i = 0\n , flags = this._terminal.curAttr >> 18\n , fg = (this._terminal.curAttr >> 9) & 0x1ff\n , bg = this._terminal.curAttr & 0x1ff\n , p;\n\n for (; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= 1;\n } else if (p === 4) {\n // underlined text\n flags |= 2;\n } else if (p === 5) {\n // blink\n flags |= 4;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= 8;\n } else if (p === 8) {\n // invisible\n flags |= 16;\n } else if (p === 22) {\n // not bold\n flags &= ~1;\n } else if (p === 24) {\n // not underlined\n flags &= ~2;\n } else if (p === 25) {\n // not blink\n flags &= ~4;\n } else if (p === 27) {\n // not inverse\n flags &= ~8;\n } else if (p === 28) {\n // not invisible\n flags &= ~16;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.y + 1)\n + ';'\n + (this._terminal.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.scrollTop = 0;\n this._terminal.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.x = this._terminal.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.scrollTop = (params[0] || 1) - 1;\n this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.x = 0;\n this._terminal.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.savedX = this._terminal.x;\n this._terminal.savedY = this._terminal.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.x = this._terminal.savedX || 0;\n this._terminal.y = this._terminal.savedY || 0;\n }\n}\n\nconst wcwidth = (function(opts) {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs) {\n let min = 0;\n let max = COMBINING.length - 1;\n let mid;\n if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])\n return false;\n while (max >= min) {\n mid = Math.floor((min + max) / 2);\n if (ucs > COMBINING[mid][1])\n min = mid + 1;\n else if (ucs < COMBINING[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidth(ucs) {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWide(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWide(ucs) {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6) ||\n (ucs >= 0x20000 && ucs <= 0x2fffd) ||\n (ucs >= 0x30000 && ucs <= 0x3fffd)));\n }\n return wcwidth;\n})({nul: 0, control: 0}); // configurable options\n","/**\n * @license MIT\n */\n\ninterface ListenerType {\n (): void;\n listener?: () => void;\n};\n\nexport class EventEmitter {\n private _events: {[type: string]: ListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type, listener): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type, listener): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type, listener): any {\n function on() {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n return listener.apply(this, args);\n }\n (on).listener = listener;\n return this.on(type, on);\n }\n\n public emit(type): void {\n if (!this._events[type]) {\n return;\n }\n\n let args = Array.prototype.slice.call(arguments, 1);\n let obj = this._events[type];\n\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type): ListenerType[] {\n return this._events[type] || [];\n }\n}\n","/**\n * @license MIT\n */\n\n/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart() {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent) {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend() {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent) {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean) {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges() {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean) {\n if (!this.isComposing) {\n return;\n }\n const cursor = this.terminal.element.querySelector('.terminal-cursor');\n if (cursor) {\n // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n // the .xterm element.\n const xtermRows = this.terminal.element.querySelector('.xterm-rows');\n const cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n this.compositionView.style.left = cursor.offsetLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cursor.offsetHeight + 'px';\n this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursor.offsetLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition() {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * @license MIT\n */\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: {[key: string]: {[key: string]: string}} = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n",null],"names":[],"mappings":"AeAA;;;ADSa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AD3OA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AACA;AAAA;AApNa;;;;;;;ADRb;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAAC;;;;;;;ADtEA;AAED;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA9Da;;;;;;;ADJb;AACA;AASA;AAEA;AAAA;AAAA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAkEA;AAEA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAv7Ca;AAy7Cb;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ADxiDA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAKA;AAeA;AAFA;AAGA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAMA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AAAA;AAOA;AACA;AAEA;AACA;AACA;AACA;AAQA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAlTmB;AANN;;;;;;;ADhCb;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAKA;AACA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAIA;AACA;AAGA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AAAA;AArda;;;;;;;AD3Jb;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAC;AAED;AAEA;AAMA;AAAA;AAJA;AACA;AACA;AAKA;AACA;AACA;AAKA;AAQA;AACA;AACA;AACA;AACA;AACA;AAMA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAuBA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AAGA;AAAA;AACA;AAEA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAtQa;AA2Qb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ADtSA;AAYA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AA/Ga;;;;;;;ADcb;AACA;AAMA;AAEA;AACA;AAEA;AACA;AAbA;AAmBA;AAGA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAbA;AAoBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAtBA;AAqCA;AACA;AAMA;AACA;AAGA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApDA;;;;;;;AD/FA;AAEA;AACA;AACA;AAEa;AACA;AAKA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ADhBb;AAKA;AAAA;AAOA;AAAA;AAEA;AACA;;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAnDa;;;;;;;ADJb;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAXA;AAaA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAWA;AAAA;AACA;AACA;;;AAAA;AAUA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AAhLa;;;;;;;ADKb;AACA;AACA;AAFA;AAEC;;;;;;;ADDD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAgBA;AAOA;AAMA;AAOA;AAkBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAIA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAMA;AAKA;AAKA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAGA;AACA;AAQA;AAGA;AAGA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAKA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAIA;AAGA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAIA;AAOA;AACA;AAQA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAYA;AACA;AAKA;AACA;AAIA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AACA;AAGA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAGA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AAGA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAQA;AACA;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAOA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AASA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAQA;AACA;AACA;AAEA;;;"} \ No newline at end of file diff --git a/package.json b/package.json index c1d07e3c..03b725b6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "2.4.0", + "version": "2.5.0", "ignore": [ "demo", "test", From bf34980c4358d97e45a6dc75c22dc0ba54fc76ab Mon Sep 17 00:00:00 2001 From: Saul Costa Date: Thu, 6 Apr 2017 12:50:41 -0700 Subject: [PATCH 205/211] Added Codevolve.com to README We use xterm.js for our courses at Codevolve. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d0de1569..37a92f40 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**WebSSH2**](https://github.com/billchurch/WebSSH2): A web based SSH2 client using `xterm.js`, socket.io, and ssh2. - [**Spyder Terminal**](https://github.com/spyder-ide/spyder-terminal): A full fledged system terminal embedded on Spyder IDE. - [**Cloud Commander**](https://cloudcmd.io "Cloud Commander"): Orthodox web file manager with console and editor. +- [**Codevolve**](https://www.codevolve.com "Codevolve"): Online platform for interactive coding and web development courses. Live container-backed terminal uses `xterm.js`. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From b38be3a1d0a8747055d0428a95dc75770c08c71f Mon Sep 17 00:00:00 2001 From: Gary Ritchie Date: Fri, 14 Apr 2017 10:50:15 -0700 Subject: [PATCH 206/211] Update README with RStudio under real-world uses. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 37a92f40..8a4dd6c4 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Spyder Terminal**](https://github.com/spyder-ide/spyder-terminal): A full fledged system terminal embedded on Spyder IDE. - [**Cloud Commander**](https://cloudcmd.io "Cloud Commander"): Orthodox web file manager with console and editor. - [**Codevolve**](https://www.codevolve.com "Codevolve"): Online platform for interactive coding and web development courses. Live container-backed terminal uses `xterm.js`. +- [**RStudio**](https://www.rstudio.com/products/RStudio "RStudio"): RStudio is an integrated development environment (IDE) for R. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From 5cafcdb695b0493144fcd23db94bd1b5dea59402 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Apr 2017 11:22:18 -0700 Subject: [PATCH 207/211] Keep cursor blink interval after a reset Fixes #638 --- src/xterm.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xterm.js b/src/xterm.js index 09c03322..777e65f9 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2193,8 +2193,10 @@ Terminal.prototype.reset = function() { this.options.rows = this.rows; this.options.cols = this.cols; var customKeydownHandler = this.customKeydownHandler; + var cursorBlinkInterval = this.cursorBlinkInterval; Terminal.call(this, this.options); this.customKeydownHandler = customKeydownHandler; + this.cursorBlinkInterval = cursorBlinkInterval; this.refresh(0, this.rows - 1); this.viewport.syncScrollArea(); }; From 46d62f4972c97318915d98c8b6c6bedb117a1136 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Apr 2017 18:16:48 -0700 Subject: [PATCH 208/211] Support cursorStyle selection in demo --- demo/index.html | 10 ++++++++++ demo/main.js | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/demo/index.html b/demo/index.html index 0d8efac3..d4574aa3 100644 --- a/demo/index.html +++ b/demo/index.html @@ -19,6 +19,16 @@

+

+ +

diff --git a/demo/main.js b/demo/main.js index b262ce53..c8d03ae1 100644 --- a/demo/main.js +++ b/demo/main.js @@ -9,6 +9,7 @@ var term, var terminalContainer = document.getElementById('terminal-container'), optionElements = { cursorBlink: document.querySelector('#option-cursor-blink'), + cursorStyle: document.querySelector('#option-cursor-style'), scrollback: document.querySelector('#option-scrollback'), tabstopwidth: document.querySelector('#option-tabstopwidth') }, @@ -32,6 +33,9 @@ rowsElement.addEventListener('change', setTerminalSize); optionElements.cursorBlink.addEventListener('change', function () { term.setOption('cursorBlink', optionElements.cursorBlink.checked); }); +optionElements.cursorStyle.addEventListener('change', function () { + term.setOption('cursorStyle', optionElements.cursorStyle.value); +}); optionElements.scrollback.addEventListener('change', function () { term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); }); From 8f3e2b645a1e8fdf01d817b12b59a7b8f61cacdd Mon Sep 17 00:00:00 2001 From: Justin Mecham Date: Sun, 23 Apr 2017 14:36:01 -0400 Subject: [PATCH 209/211] Added "Terminal for Atom" to Real-World Uses. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a4dd6c4..f7d2bd8e 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Cloud Commander**](https://cloudcmd.io "Cloud Commander"): Orthodox web file manager with console and editor. - [**Codevolve**](https://www.codevolve.com "Codevolve"): Online platform for interactive coding and web development courses. Live container-backed terminal uses `xterm.js`. - [**RStudio**](https://www.rstudio.com/products/RStudio "RStudio"): RStudio is an integrated development environment (IDE) for R. +- [**Terminal for Atom**](https://github.com/jsmecham/atom-terminal-tab): A simple terminal for the Atom text editor. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From 35f746c92557d73490a340c84224b26f898d78a4 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Wed, 26 Apr 2017 13:37:00 +0300 Subject: [PATCH 210/211] Add `focus` argument in `Terminal.prototype.open` Fix #640 --- src/xterm.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index 777e65f9..75d0bc45 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -607,8 +607,9 @@ Terminal.prototype.insertRow = function (row) { * Opens the terminal within an element. * * @param {HTMLElement} parent The element to create the terminal within. + * @param {boolean} focus Focus the terminal, after it gets instantiated in the DOM */ -Terminal.prototype.open = function(parent) { +Terminal.prototype.open = function(parent, focus) { var self=this, i=0, div; this.parent = parent || this.parent; @@ -629,7 +630,7 @@ Terminal.prototype.open = function(parent) { this.element.classList.add('xterm-theme-' + this.theme); this.setCursorBlinking(this.options.cursorBlink); - this.element.style.height + this.element.style.height; this.element.setAttribute('tabindex', 0); this.viewportElement = document.createElement('div'); @@ -696,8 +697,23 @@ Terminal.prototype.open = function(parent) { // need to be taken on the document. this.initGlobal(); - // Ensure there is a Terminal.focus. - this.focus(); + /** + * Automatic focus functionality. + * TODO: Default to `false` starting with xterm.js 3.0. + */ + if (typeof focus == 'undefined') { + let message = 'You did not pass the `focus` argument in `Terminal.prototype.open()`.\n'; + + message += 'The `focus` argument now defaults to `true` but starting with xterm.js 3.0 '; + message += 'it will default to `false`.'; + + console.warn(message); + focus = true; + } + + if (focus) { + this.focus(); + } on(this.element, 'click', function() { var selection = document.getSelection(), From 938c011e634bef54ac5b95bdaa4c10fd7fed7e70 Mon Sep 17 00:00:00 2001 From: Martin Chloride Date: Mon, 1 May 2017 17:12:07 -0400 Subject: [PATCH 211/211] Added "Eclipse Orion" to "Real-World Uses". --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f7d2bd8e..05c9651c 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Codevolve**](https://www.codevolve.com "Codevolve"): Online platform for interactive coding and web development courses. Live container-backed terminal uses `xterm.js`. - [**RStudio**](https://www.rstudio.com/products/RStudio "RStudio"): RStudio is an integrated development environment (IDE) for R. - [**Terminal for Atom**](https://github.com/jsmecham/atom-terminal-tab): A simple terminal for the Atom text editor. +- [**Eclipse Orion**](https://orionhub.org): A modern, open source software development environment that runs in the cloud. Code, deploy and run in the cloud. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list.