This commit is contained in:
2019-06-07 23:04:57 +08:00
commit 36b92f19e0
67 changed files with 18266 additions and 0 deletions

View File

@ -0,0 +1,104 @@
(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.attach = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function attach(term, socket, bidirectional, buffered) {
var addonTerminal = term;
bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional;
addonTerminal.__socket = socket;
addonTerminal.__flushBuffer = function () {
addonTerminal.write(addonTerminal.__attachSocketBuffer);
addonTerminal.__attachSocketBuffer = null;
};
addonTerminal.__pushToBuffer = function (data) {
if (addonTerminal.__attachSocketBuffer) {
addonTerminal.__attachSocketBuffer += data;
}
else {
addonTerminal.__attachSocketBuffer = data;
setTimeout(addonTerminal.__flushBuffer, 10);
}
};
var myTextDecoder;
addonTerminal.__getMessage = function (ev) {
var str;
if (typeof ev.data === 'object') {
if (!myTextDecoder) {
myTextDecoder = new TextDecoder();
}
if (ev.data instanceof ArrayBuffer) {
str = myTextDecoder.decode(ev.data);
displayData(str);
}
else {
var fileReader_1 = new FileReader();
fileReader_1.addEventListener('load', function () {
str = myTextDecoder.decode(fileReader_1.result);
displayData(str);
});
fileReader_1.readAsArrayBuffer(ev.data);
}
}
else if (typeof ev.data === 'string') {
displayData(ev.data);
}
else {
throw Error("Cannot handle \"" + typeof ev.data + "\" websocket message.");
}
};
function displayData(str, data) {
if (buffered) {
addonTerminal.__pushToBuffer(str || data);
}
else {
addonTerminal.write(str || data);
}
}
addonTerminal.__sendData = function (data) {
if (socket.readyState !== 1) {
return;
}
socket.send(data);
};
addonTerminal._core.register(addSocketListener(socket, 'message', addonTerminal.__getMessage));
if (bidirectional) {
addonTerminal._core.register(addonTerminal.addDisposableListener('data', addonTerminal.__sendData));
}
addonTerminal._core.register(addSocketListener(socket, 'close', function () { return detach(addonTerminal, socket); }));
addonTerminal._core.register(addSocketListener(socket, 'error', function () { return detach(addonTerminal, socket); }));
}
exports.attach = attach;
function addSocketListener(socket, type, handler) {
socket.addEventListener(type, handler);
return {
dispose: function () {
if (!handler) {
return;
}
socket.removeEventListener(type, handler);
handler = null;
}
};
}
function detach(term, socket) {
var addonTerminal = term;
addonTerminal.off('data', addonTerminal.__sendData);
socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket;
if (socket) {
socket.removeEventListener('message', addonTerminal.__getMessage);
}
delete addonTerminal.__socket;
}
exports.detach = detach;
function apply(terminalConstructor) {
terminalConstructor.prototype.attach = function (socket, bidirectional, buffered) {
attach(this, socket, bidirectional, buffered);
};
terminalConstructor.prototype.detach = function (socket) {
detach(this, socket);
};
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=attach.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,51 @@
(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.fit = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function proposeGeometry(term) {
if (!term.element.parentElement) {
return null;
}
var parentElementStyle = window.getComputedStyle(term.element.parentElement);
var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')));
var elementStyle = window.getComputedStyle(term.element);
var elementPadding = {
top: parseInt(elementStyle.getPropertyValue('padding-top')),
bottom: parseInt(elementStyle.getPropertyValue('padding-bottom')),
right: parseInt(elementStyle.getPropertyValue('padding-right')),
left: parseInt(elementStyle.getPropertyValue('padding-left'))
};
var elementPaddingVer = elementPadding.top + elementPadding.bottom;
var elementPaddingHor = elementPadding.right + elementPadding.left;
var availableHeight = parentElementHeight - elementPaddingVer;
var availableWidth = parentElementWidth - elementPaddingHor - term._core.viewport.scrollBarWidth;
var geometry = {
cols: Math.floor(availableWidth / term._core.renderer.dimensions.actualCellWidth),
rows: Math.floor(availableHeight / term._core.renderer.dimensions.actualCellHeight)
};
return geometry;
}
exports.proposeGeometry = proposeGeometry;
function fit(term) {
var geometry = proposeGeometry(term);
if (geometry) {
if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
term._core.renderer.clear();
term.resize(geometry.cols, geometry.rows);
}
}
}
exports.fit = fit;
function apply(terminalConstructor) {
terminalConstructor.prototype.proposeGeometry = function () {
return proposeGeometry(this);
};
terminalConstructor.prototype.fit = function () {
fit(this);
};
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=fit.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"fit.js","sources":["../../../src/addons/fit/fit.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Fit terminal columns and rows to the dimensions of its DOM element.\n *\n * ## Approach\n *\n * Rows: Truncate the division of the terminal parent element height by the\n * terminal row height.\n * Columns: Truncate the division of the terminal parent element width by the\n * terminal character width (apply display: inline at the terminal\n * row and truncate its width with the current number of columns).\n */\n\nimport { Terminal } from 'xterm';\n\nexport interface IGeometry {\n rows: number;\n cols: number;\n}\n\nexport function proposeGeometry(term: Terminal): IGeometry {\n if (!term.element.parentElement) {\n return null;\n }\n const parentElementStyle = window.getComputedStyle(term.element.parentElement);\n const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));\n const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')));\n const elementStyle = window.getComputedStyle(term.element);\n const elementPadding = {\n top: parseInt(elementStyle.getPropertyValue('padding-top')),\n bottom: parseInt(elementStyle.getPropertyValue('padding-bottom')),\n right: parseInt(elementStyle.getPropertyValue('padding-right')),\n left: parseInt(elementStyle.getPropertyValue('padding-left'))\n };\n const elementPaddingVer = elementPadding.top + elementPadding.bottom;\n const elementPaddingHor = elementPadding.right + elementPadding.left;\n const availableHeight = parentElementHeight - elementPaddingVer;\n const availableWidth = parentElementWidth - elementPaddingHor - (<any>term)._core.viewport.scrollBarWidth;\n const geometry = {\n cols: Math.floor(availableWidth / (<any>term)._core.renderer.dimensions.actualCellWidth),\n rows: Math.floor(availableHeight / (<any>term)._core.renderer.dimensions.actualCellHeight)\n };\n return geometry;\n}\n\nexport function fit(term: Terminal): void {\n const geometry = proposeGeometry(term);\n if (geometry) {\n // Force a full render\n if (term.rows !== geometry.rows || term.cols !== geometry.cols) {\n (<any>term)._core.renderer.clear();\n term.resize(geometry.cols, geometry.rows);\n }\n }\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n (<any>terminalConstructor.prototype).proposeGeometry = function (): IGeometry {\n return proposeGeometry(this);\n };\n\n (<any>terminalConstructor.prototype).fit = function (): void {\n fit(this);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAvBA;AAyBA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AATA;AAWA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AARA;"}

View File

@ -0,0 +1,10 @@
.xterm.fullscreen {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: auto;
height: auto;
z-index: 255;
}

View File

@ -0,0 +1,29 @@
(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.fullscreen = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function toggleFullScreen(term, fullscreen) {
var fn;
if (typeof fullscreen === 'undefined') {
fn = (term.element.classList.contains('fullscreen')) ?
term.element.classList.remove : term.element.classList.add;
}
else if (!fullscreen) {
fn = term.element.classList.remove;
}
else {
fn = term.element.classList.add;
}
fn = fn.bind(term.element.classList);
fn('fullscreen');
}
exports.toggleFullScreen = toggleFullScreen;
function apply(terminalConstructor) {
terminalConstructor.prototype.toggleFullScreen = function (fullscreen) {
toggleFullScreen(this, fullscreen);
};
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=fullscreen.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"fullscreen.js","sources":["../../../src/addons/fullscreen/fullscreen.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal } from 'xterm';\n\n/**\n * Toggle the given terminal's fullscreen mode.\n * @param term The terminal to toggle full screen mode\n * @param fullscreen Toggle fullscreen on (true) or off (false)\n */\nexport function toggleFullScreen(term: Terminal, fullscreen: boolean): void {\n let fn: (...tokens: string[]) => void;\n\n if (typeof fullscreen === 'undefined') {\n fn = (term.element.classList.contains('fullscreen')) ?\n term.element.classList.remove : term.element.classList.add;\n } else if (!fullscreen) {\n fn = term.element.classList.remove;\n } else {\n fn = term.element.classList.add;\n }\n\n fn = fn.bind(term.element.classList);\n fn('fullscreen');\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n (<any>terminalConstructor.prototype).toggleFullScreen = function (fullscreen: boolean): void {\n toggleFullScreen(this, fullscreen);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADYA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAdA;AAgBA;AACA;AACA;AACA;AACA;AAJA;"}

View File

@ -0,0 +1,235 @@
(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.search = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\;:"\',./<>?';
var LINES_CACHE_TIME_TO_LIVE = 15 * 1000;
var SearchHelper = (function () {
function SearchHelper(_terminal) {
this._terminal = _terminal;
this._linesCache = null;
this._linesCacheTimeoutId = 0;
this._destroyLinesCache = this._destroyLinesCache.bind(this);
}
SearchHelper.prototype.findNext = function (term, searchOptions) {
var selectionManager = this._terminal._core.selectionManager;
var incremental = searchOptions.incremental;
var result;
if (!term || term.length === 0) {
selectionManager.clearSelection();
return false;
}
var startCol = 0;
var startRow = this._terminal._core.buffer.ydisp;
if (selectionManager.selectionEnd) {
if (this._terminal.getSelection().length !== 0) {
startRow = incremental ? selectionManager.selectionStart[1] : selectionManager.selectionEnd[1];
startCol = incremental ? selectionManager.selectionStart[0] : selectionManager.selectionEnd[0];
}
}
this._initLinesCache();
result = this._findInLine(term, startRow, startCol, searchOptions);
if (!result) {
for (var y = startRow + 1; y < this._terminal._core.buffer.ybase + this._terminal.rows; y++) {
result = this._findInLine(term, y, 0, searchOptions);
if (result) {
break;
}
}
}
if (!result) {
for (var y = 0; y <= startRow; y++) {
result = this._findInLine(term, y, 0, searchOptions);
if (result) {
break;
}
}
}
return this._selectResult(result);
};
SearchHelper.prototype.findPrevious = function (term, searchOptions) {
var selectionManager = this._terminal._core.selectionManager;
var result;
if (!term || term.length === 0) {
selectionManager.clearSelection();
return false;
}
var isReverseSearch = true;
var startRow = this._terminal._core.buffer.ydisp;
var startCol = this._terminal._core.buffer.lines.get(startRow).length;
if (selectionManager.selectionStart) {
if (this._terminal.getSelection().length !== 0) {
startRow = selectionManager.selectionStart[1];
startCol = selectionManager.selectionStart[0];
}
}
this._initLinesCache();
result = this._findInLine(term, startRow, startCol, searchOptions, isReverseSearch);
if (!result) {
for (var y = startRow - 1; y >= 0; y--) {
result = this._findInLine(term, y, this._terminal._core.buffer.lines.get(y).length, searchOptions, isReverseSearch);
if (result) {
break;
}
}
}
if (!result) {
var searchFrom = this._terminal._core.buffer.ybase + this._terminal.rows - 1;
for (var y = searchFrom; y >= startRow; y--) {
result = this._findInLine(term, y, this._terminal._core.buffer.lines.get(y).length, searchOptions, isReverseSearch);
if (result) {
break;
}
}
}
return this._selectResult(result);
};
SearchHelper.prototype._initLinesCache = function () {
var _this = this;
if (!this._linesCache) {
this._linesCache = new Array(this._terminal._core.buffer.length);
this._terminal.on('cursormove', this._destroyLinesCache);
}
window.clearTimeout(this._linesCacheTimeoutId);
this._linesCacheTimeoutId = window.setTimeout(function () { return _this._destroyLinesCache(); }, LINES_CACHE_TIME_TO_LIVE);
};
SearchHelper.prototype._destroyLinesCache = function () {
this._linesCache = null;
this._terminal.off('cursormove', this._destroyLinesCache);
if (this._linesCacheTimeoutId) {
window.clearTimeout(this._linesCacheTimeoutId);
this._linesCacheTimeoutId = 0;
}
};
SearchHelper.prototype._isWholeWord = function (searchIndex, line, term) {
return (((searchIndex === 0) || (NON_WORD_CHARACTERS.indexOf(line[searchIndex - 1]) !== -1)) &&
(((searchIndex + term.length) === line.length) || (NON_WORD_CHARACTERS.indexOf(line[searchIndex + term.length]) !== -1)));
};
SearchHelper.prototype._findInLine = function (term, row, col, searchOptions, isReverseSearch) {
if (searchOptions === void 0) { searchOptions = {}; }
if (isReverseSearch === void 0) { isReverseSearch = false; }
if (this._terminal._core.buffer.lines.get(row).isWrapped) {
return;
}
var stringLine = this._linesCache ? this._linesCache[row] : void 0;
if (stringLine === void 0) {
stringLine = this.translateBufferLineToStringWithWrap(row, true);
if (this._linesCache) {
this._linesCache[row] = stringLine;
}
}
var searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();
var searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();
var resultIndex = -1;
if (searchOptions.regex) {
var searchRegex = RegExp(searchTerm, 'g');
var foundTerm = void 0;
if (isReverseSearch) {
while (foundTerm = searchRegex.exec(searchStringLine.slice(0, col))) {
resultIndex = searchRegex.lastIndex - foundTerm[0].length;
term = foundTerm[0];
searchRegex.lastIndex -= (term.length - 1);
}
}
else {
foundTerm = searchRegex.exec(searchStringLine.slice(col));
if (foundTerm && foundTerm[0].length > 0) {
resultIndex = col + (searchRegex.lastIndex - foundTerm[0].length);
term = foundTerm[0];
}
}
}
else {
if (isReverseSearch) {
if (col - searchTerm.length >= 0) {
resultIndex = searchStringLine.lastIndexOf(searchTerm, col - searchTerm.length);
}
}
else {
resultIndex = searchStringLine.indexOf(searchTerm, col);
}
}
if (resultIndex >= 0) {
if (resultIndex >= this._terminal.cols) {
row += Math.floor(resultIndex / this._terminal.cols);
resultIndex = resultIndex % this._terminal.cols;
}
if (searchOptions.wholeWord && !this._isWholeWord(resultIndex, searchStringLine, term)) {
return;
}
var line = this._terminal._core.buffer.lines.get(row);
for (var i = 0; i < resultIndex; i++) {
var charData = line.get(i);
var char = charData[1];
if (char.length > 1) {
resultIndex -= char.length - 1;
}
var charWidth = charData[2];
if (charWidth === 0) {
resultIndex++;
}
}
return {
term: term,
col: resultIndex,
row: row
};
}
};
SearchHelper.prototype.translateBufferLineToStringWithWrap = function (lineIndex, trimRight) {
var lineString = '';
var lineWrapsToNext;
do {
var nextLine = this._terminal._core.buffer.lines.get(lineIndex + 1);
lineWrapsToNext = nextLine ? nextLine.isWrapped : false;
lineString += this._terminal._core.buffer.translateBufferLineToString(lineIndex, !lineWrapsToNext && trimRight).substring(0, this._terminal.cols);
lineIndex++;
} while (lineWrapsToNext);
return lineString;
};
SearchHelper.prototype._selectResult = function (result) {
if (!result) {
this._terminal.clearSelection();
return false;
}
this._terminal._core.selectionManager.setSelection(result.col, result.row, result.term.length);
this._terminal.scrollLines(result.row - this._terminal._core.buffer.ydisp);
return true;
};
return SearchHelper;
}());
exports.SearchHelper = SearchHelper;
},{}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var SearchHelper_1 = require("./SearchHelper");
function findNext(terminal, term, searchOptions) {
if (searchOptions === void 0) { searchOptions = {}; }
var addonTerminal = terminal;
if (!addonTerminal.__searchHelper) {
addonTerminal.__searchHelper = new SearchHelper_1.SearchHelper(addonTerminal);
}
return addonTerminal.__searchHelper.findNext(term, searchOptions);
}
exports.findNext = findNext;
function findPrevious(terminal, term, searchOptions) {
var addonTerminal = terminal;
if (!addonTerminal.__searchHelper) {
addonTerminal.__searchHelper = new SearchHelper_1.SearchHelper(addonTerminal);
}
return addonTerminal.__searchHelper.findPrevious(term, searchOptions);
}
exports.findPrevious = findPrevious;
function apply(terminalConstructor) {
terminalConstructor.prototype.findNext = function (term, searchOptions) {
return findNext(this, term, searchOptions);
};
terminalConstructor.prototype.findPrevious = function (term, searchOptions) {
return findPrevious(this, term, searchOptions);
};
}
exports.apply = apply;
},{"./SearchHelper":1}]},{},[2])(2)
});
//# sourceMappingURL=search.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,69 @@
(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.terminado = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function terminadoAttach(term, socket, bidirectional, buffered) {
var addonTerminal = term;
bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional;
addonTerminal.__socket = socket;
addonTerminal.__flushBuffer = function () {
addonTerminal.write(addonTerminal.__attachSocketBuffer);
addonTerminal.__attachSocketBuffer = null;
};
addonTerminal.__pushToBuffer = function (data) {
if (addonTerminal.__attachSocketBuffer) {
addonTerminal.__attachSocketBuffer += data;
}
else {
addonTerminal.__attachSocketBuffer = data;
setTimeout(addonTerminal.__flushBuffer, 10);
}
};
addonTerminal.__getMessage = function (ev) {
var data = JSON.parse(ev.data);
if (data[0] === 'stdout') {
if (buffered) {
addonTerminal.__pushToBuffer(data[1]);
}
else {
addonTerminal.write(data[1]);
}
}
};
addonTerminal.__sendData = function (data) {
socket.send(JSON.stringify(['stdin', data]));
};
addonTerminal.__setSize = function (size) {
socket.send(JSON.stringify(['set_size', size.rows, size.cols]));
};
socket.addEventListener('message', addonTerminal.__getMessage);
if (bidirectional) {
addonTerminal.on('data', addonTerminal.__sendData);
}
addonTerminal.on('resize', addonTerminal.__setSize);
socket.addEventListener('close', function () { return terminadoDetach(addonTerminal, socket); });
socket.addEventListener('error', function () { return terminadoDetach(addonTerminal, socket); });
}
exports.terminadoAttach = terminadoAttach;
function terminadoDetach(term, socket) {
var addonTerminal = term;
addonTerminal.off('data', addonTerminal.__sendData);
socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket;
if (socket) {
socket.removeEventListener('message', addonTerminal.__getMessage);
}
delete addonTerminal.__socket;
}
exports.terminadoDetach = terminadoDetach;
function apply(terminalConstructor) {
terminalConstructor.prototype.terminadoAttach = function (socket, bidirectional, buffered) {
return terminadoAttach(this, socket, bidirectional, buffered);
};
terminalConstructor.prototype.terminadoDetach = function (socket) {
return terminadoDetach(this, socket);
};
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=terminado.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"terminado.js","sources":["../../../src/addons/terminado/terminado.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This module provides methods for attaching a terminal to a terminado\n * WebSocket stream.\n */\n\nimport { Terminal } from 'xterm';\nimport { ITerminadoAddonTerminal } from './Interfaces';\n\n/**\n * Attaches the given terminal to the given socket.\n *\n * @param term The terminal to be attached to the given socket.\n * @param socket The socket to attach the current terminal.\n * @param bidirectional Whether the terminal should send data to the socket as well.\n * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum\n * frequency of 1 rendering per 10ms.\n */\nexport function terminadoAttach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean): void {\n const addonTerminal = <ITerminadoAddonTerminal>term;\n bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional;\n addonTerminal.__socket = socket;\n\n addonTerminal.__flushBuffer = () => {\n addonTerminal.write(addonTerminal.__attachSocketBuffer);\n addonTerminal.__attachSocketBuffer = null;\n };\n\n addonTerminal.__pushToBuffer = (data: string) => {\n if (addonTerminal.__attachSocketBuffer) {\n addonTerminal.__attachSocketBuffer += data;\n } else {\n addonTerminal.__attachSocketBuffer = data;\n setTimeout(addonTerminal.__flushBuffer, 10);\n }\n };\n\n addonTerminal.__getMessage = (ev: MessageEvent) => {\n const data = JSON.parse(ev.data);\n if (data[0] === 'stdout') {\n if (buffered) {\n addonTerminal.__pushToBuffer(data[1]);\n } else {\n addonTerminal.write(data[1]);\n }\n }\n };\n\n addonTerminal.__sendData = (data: string) => {\n socket.send(JSON.stringify(['stdin', data]));\n };\n\n addonTerminal.__setSize = (size: {rows: number, cols: number}) => {\n socket.send(JSON.stringify(['set_size', size.rows, size.cols]));\n };\n\n socket.addEventListener('message', addonTerminal.__getMessage);\n\n if (bidirectional) {\n addonTerminal.on('data', addonTerminal.__sendData);\n }\n addonTerminal.on('resize', addonTerminal.__setSize);\n\n socket.addEventListener('close', () => terminadoDetach(addonTerminal, socket));\n socket.addEventListener('error', () => terminadoDetach(addonTerminal, socket));\n}\n\n/**\n * Detaches the given terminal from the given socket\n *\n * @param term The terminal to be detached from the given socket.\n * @param socket The socket from which to detach the current terminal.\n */\nexport function terminadoDetach(term: Terminal, socket: WebSocket): void {\n const addonTerminal = <ITerminadoAddonTerminal>term;\n addonTerminal.off('data', addonTerminal.__sendData);\n\n socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket;\n\n if (socket) {\n socket.removeEventListener('message', addonTerminal.__getMessage);\n }\n\n delete addonTerminal.__socket;\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n /**\n * Attaches the current terminal to the given socket\n *\n * @param socket - The socket to attach the current terminal.\n * @param bidirectional - Whether the terminal should send data to the socket as well.\n * @param buffered - Whether the rendering of incoming data should happen instantly or at a\n * maximum frequency of 1 rendering per 10ms.\n */\n (<any>terminalConstructor.prototype).terminadoAttach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void {\n return terminadoAttach(this, socket, bidirectional, buffered);\n };\n\n /**\n * Detaches the current terminal from the given socket.\n *\n * @param socket The socket from which to detach the current terminal.\n */\n (<any>terminalConstructor.prototype).terminadoDetach = function (socket: WebSocket): void {\n return terminadoDetach(this, socket);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADoBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AA/CA;AAuDA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAXA;AAaA;AASA;AACA;AACA;AAOA;AACA;AACA;AACA;AArBA;"}

View File

@ -0,0 +1,41 @@
(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.webLinks = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
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\\.\\-%~:]*)*([^:"\'\\s])';
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);
function handleLink(event, uri) {
window.open(uri, '_blank');
}
function webLinksInit(term, handler, options) {
if (handler === void 0) { handler = handleLink; }
if (options === void 0) { options = {}; }
options.matchIndex = 1;
term.registerLinkMatcher(strictUrlRegex, handler, options);
}
exports.webLinksInit = webLinksInit;
function apply(terminalConstructor) {
terminalConstructor.prototype.webLinksInit = function (handler, options) {
webLinksInit(this, handler, options);
};
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=webLinks.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"webLinks.js","sources":["../../../src/addons/webLinks/webLinks.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal, ILinkMatcherOptions } from 'xterm';\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\\\\.\\\\-%~:]*)*([^:\"\\'\\\\s])';\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\nfunction handleLink(event: MouseEvent, uri: string): void {\n window.open(uri, '_blank');\n}\n\n/**\n * Initialize the web links addon, registering the link matcher.\n * @param term The terminal to use web links within.\n * @param handler A custom handler to use.\n * @param options Custom options to use, matchIndex will always be ignored.\n */\nexport function webLinksInit(term: Terminal, handler: (event: MouseEvent, uri: string) => void = handleLink, options: ILinkMatcherOptions = {}): void {\n options.matchIndex = 1;\n term.registerLinkMatcher(strictUrlRegex, handler, options);\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n (<any>terminalConstructor.prototype).webLinksInit = function (handler?: (event: MouseEvent, uri: string) => void, options?: ILinkMatcherOptions): void {\n webLinksInit(this, handler, options);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAQA;AAAA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAJA;"}

View File

@ -0,0 +1,33 @@
(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.winptyCompat = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var CHAR_DATA_CODE_INDEX = 3;
var NULL_CELL_CODE = 0;
var WHITESPACE_CELL_CODE = 32;
function winptyCompatInit(terminal) {
var addonTerminal = terminal;
var isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
if (!isWindows) {
return;
}
addonTerminal._core.isWinptyCompatEnabled = true;
addonTerminal.on('linefeed', function () {
var line = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y - 1);
var lastChar = line.get(addonTerminal.cols - 1);
if (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE) {
var nextLine = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y);
nextLine.isWrapped = true;
}
});
}
exports.winptyCompatInit = winptyCompatInit;
function apply(terminalConstructor) {
terminalConstructor.prototype.winptyCompatInit = function () {
winptyCompatInit(this);
};
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=winptyCompat.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"winptyCompat.js","sources":["../../../src/addons/winptyCompat/winptyCompat.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal } from 'xterm';\nimport { IWinptyCompatAddonTerminal } from './Interfaces';\n\nconst CHAR_DATA_CODE_INDEX = 3;\nconst NULL_CELL_CODE = 0;\nconst WHITESPACE_CELL_CODE = 32;\n\nexport function winptyCompatInit(terminal: Terminal): void {\n const addonTerminal = <IWinptyCompatAddonTerminal>terminal;\n\n // Don't do anything when the platform is not Windows\n const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;\n if (!isWindows) {\n return;\n }\n\n (addonTerminal._core as any).isWinptyCompatEnabled = true;\n\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n addonTerminal.on('linefeed', () => {\n const line = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y - 1);\n const lastChar = line.get(addonTerminal.cols - 1);\n\n if (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE) {\n const nextLine = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y);\n nextLine.isWrapped = true;\n }\n });\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n (<any>terminalConstructor.prototype).winptyCompatInit = function (): void {\n winptyCompatInit(this);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADQA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAEA;AAYA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AA9BA;AAgCA;AACA;AACA;AACA;AACA;AAJA;"}

View File

@ -0,0 +1,45 @@
(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.zmodem = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var zmodem;
function zmodemAttach(ws, opts) {
if (opts === void 0) { opts = {}; }
var term = this;
var senderFunc = function (octets) { return ws.send(new Uint8Array(octets)); };
var zsentry;
function shouldWrite() {
return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession;
}
zsentry = new zmodem.Sentry({
to_terminal: function (octets) {
if (shouldWrite()) {
term.write(String.fromCharCode.apply(String, octets));
}
},
sender: senderFunc,
on_retract: function () { return term.emit('zmodemRetract'); },
on_detect: function (detection) { return term.emit('zmodemDetect', detection); }
});
function handleWSMessage(evt) {
if (typeof evt.data === 'string') {
if (shouldWrite()) {
term.write(evt.data);
}
}
else {
zsentry.consume(evt.data);
}
}
ws.binaryType = 'arraybuffer';
ws.addEventListener('message', handleWSMessage);
}
function apply(terminalConstructor) {
zmodem = (typeof window === 'object') ? window.Zmodem : { Browser: null };
terminalConstructor.prototype.zmodemAttach = zmodemAttach;
terminalConstructor.prototype.zmodemBrowser = zmodem.Browser;
}
exports.apply = apply;
},{}]},{},[1])(1)
});
//# sourceMappingURL=zmodem.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"zmodem.js","sources":["../../../src/addons/zmodem/zmodem.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal } from 'xterm';\n\n/**\n *\n * Allow xterm.js to handle ZMODEM uploads and downloads.\n *\n * This addon is a wrapper around zmodem.js. It adds the following to the\n * Terminal class:\n *\n * - function `zmodemAttach(<WebSocket>, <Object>)` - creates a Zmodem.Sentry\n * on the passed WebSocket object. The Object passed is optional and\n * can contain:\n * - noTerminalWriteOutsideSession: Suppress writes from the Sentry\n * object to the Terminal while there is no active Session. This\n * is necessary for compatibility with, for example, the\n * `attach.js` addon.\n *\n * - event `zmodemDetect` - fired on Zmodem.Sentrys `on_detect` callback.\n * Passes the zmodem.js Detection object.\n *\n * - event `zmodemRetract` - fired on Zmodem.Sentrys `on_retract` callback.\n *\n * Youll need to provide logic to handle uploads and downloads.\n * See zmodem.jss documentation for more details.\n *\n * **IMPORTANT:** After you confirm() a zmodem.js Detection, if you have\n * used the `attach` or `terminado` addons, youll need to suspend their\n * operation for the duration of the ZMODEM session. (The demo does this\n * via `detach()` and a re-`attach()`.)\n */\n\nlet zmodem: any;\n\nexport interface IZmodemOptions {\n noTerminalWriteOutsideSession?: boolean;\n}\n\nfunction zmodemAttach(ws: WebSocket, opts: IZmodemOptions = {}): void {\n const term = this;\n const senderFunc = (octets: ArrayLike<number>) => ws.send(new Uint8Array(octets));\n\n let zsentry: any;\n\n function shouldWrite(): boolean {\n return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession;\n }\n\n zsentry = new zmodem.Sentry({\n to_terminal: (octets: ArrayLike<number>) => {\n if (shouldWrite()) {\n term.write(\n String.fromCharCode.apply(String, octets)\n );\n }\n },\n sender: senderFunc,\n on_retract: () => (<any>term).emit('zmodemRetract'),\n on_detect: (detection: any) => (<any>term).emit('zmodemDetect', detection)\n });\n\n function handleWSMessage(evt: MessageEvent): void {\n\n // In testing with xterm.jss demo the first message was\n // always text even if the rest were binary. While that\n // may be specific to xterm.jss demo, ultimately we\n // should reject anything that isnt binary.\n if (typeof evt.data === 'string') {\n if (shouldWrite()) {\n term.write(evt.data);\n }\n }\n else {\n zsentry.consume(evt.data);\n }\n }\n\n ws.binaryType = 'arraybuffer';\n ws.addEventListener('message', handleWSMessage);\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n zmodem = (typeof window === 'object') ? (<any>window).Zmodem : {Browser: null}; // Nullify browser for tests\n\n (<any>terminalConstructor.prototype).zmodemAttach = zmodemAttach;\n (<any>terminalConstructor.prototype).zmodemBrowser = zmodem.Browser;\n}\n",null],"names":[],"mappings":"ACAA;;;ADoCA;AAMA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AALA;"}