Skip to content

Instantly share code, notes, and snippets.

@SnowWarri0r
Last active March 6, 2024 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SnowWarri0r/8ae79581b2defdddd88a697b97afb21d to your computer and use it in GitHub Desktop.
Save SnowWarri0r/8ae79581b2defdddd88a697b97afb21d to your computer and use it in GitHub Desktop.
ACE Editor toml worker that can be used directly, you can see https://www.onesnowwarrior.cn/archives/136.html to know how to use
"no use strict";
!(function (window) {
if (typeof window.window != "undefined" && window.document)
return;
if (window.require && window.define)
return;
if (!window.console) {
window.console = function () {
var msgs = Array.prototype.slice.call(arguments, 0);
postMessage({ type: "log", data: msgs });
};
window.console.error =
window.console.warn =
window.console.log =
window.console.trace = window.console;
}
window.window = window;
window.ace = window;
window.onerror = function (message, file, line, col, err) {
postMessage({
type: "error", data: {
message: message,
data: err && err.data,
file: file,
line: line,
col: col,
stack: err && err.stack
}
});
};
window.normalizeModule = function (parentId, moduleName) {
// normalize plugin requires
if (moduleName.indexOf("!") !== -1) {
var chunks = moduleName.split("!");
return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]);
}
// normalize relative requires
if (moduleName.charAt(0) == ".") {
var base = parentId.split("/").slice(0, -1).join("/");
moduleName = (base ? base + "/" : "") + moduleName;
while (moduleName.indexOf(".") !== -1 && previous != moduleName) {
var previous = moduleName;
moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
}
}
return moduleName;
};
window.require = function require(parentId, id) {
if (!id) {
id = parentId;
parentId = null;
}
if (!id.charAt)
throw new Error("worker.js require() accepts only (parentId, id) as arguments");
id = window.normalizeModule(parentId, id);
var module = window.require.modules[id];
if (module) {
if (!module.initialized) {
module.initialized = true;
module.exports = module.factory().exports;
}
return module.exports;
}
if (!window.require.tlns)
return console.log("unable to load " + id);
var path = resolveModuleId(id, window.require.tlns);
if (path.slice(-3) != ".js") path += ".js";
window.require.id = id;
window.require.modules[id] = {}; // prevent infinite loop on broken modules
importScripts(path);
return window.require(parentId, id);
};
function resolveModuleId(id, paths) {
var testPath = id, tail = "";
while (testPath) {
var alias = paths[testPath];
if (typeof alias == "string") {
return alias + tail;
} else if (alias) {
return alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name);
} else if (alias === false) {
return "";
}
var i = testPath.lastIndexOf("/");
if (i === -1) break;
tail = testPath.substr(i) + tail;
testPath = testPath.slice(0, i);
}
return id;
}
window.require.modules = {};
window.require.tlns = {};
window.define = function (id, deps, factory) {
if (arguments.length == 2) {
factory = deps;
if (typeof id != "string") {
deps = id;
id = window.require.id;
}
} else if (arguments.length == 1) {
factory = id;
deps = [];
id = window.require.id;
}
if (typeof factory != "function") {
window.require.modules[id] = {
exports: factory,
initialized: true
};
return;
}
if (!deps.length)
// If there is no dependencies, we inject "require", "exports" and
// "module" as dependencies, to provide CommonJS compatibility.
deps = ["require", "exports", "module"];
var req = function (childId) {
return window.require(id, childId);
};
window.require.modules[id] = {
exports: {},
factory: function () {
var module = this;
var returnExports = factory.apply(this, deps.slice(0, factory.length).map(function (dep) {
switch (dep) {
// Because "require", "exports" and "module" aren't actual
// dependencies, we must handle them seperately.
case "require": return req;
case "exports": return module.exports;
case "module": return module;
// But for all other dependencies, we can just go ahead and
// require them.
default: return req(dep);
}
}));
if (returnExports)
module.exports = returnExports;
return module;
}
};
};
window.define.amd = {};
window.require.tlns = {};
window.initBaseUrls = function initBaseUrls(topLevelNamespaces) {
for (var i in topLevelNamespaces)
this.require.tlns[i] = topLevelNamespaces[i];
};
window.initSender = function initSender() {
var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter;
var oop = window.require("ace/lib/oop");
var Sender = function () { };
(function () {
oop.implement(this, EventEmitter);
this.callback = function (data, callbackId) {
postMessage({
type: "call",
id: callbackId,
data: data
});
};
this.emit = function (name, data) {
postMessage({
type: "event",
name: name,
data: data
});
};
}).call(Sender.prototype);
return new Sender();
};
var main = window.main = null;
var sender = window.sender = null;
window.onmessage = function (e) {
var msg = e.data;
if (msg.event && sender) {
sender._signal(msg.event, msg.data);
}
else if (msg.command) {
if (main[msg.command])
main[msg.command].apply(main, msg.args);
else if (window[msg.command])
window[msg.command].apply(window, msg.args);
else
throw new Error("Unknown command:" + msg.command);
}
else if (msg.init) {
window.initBaseUrls(msg.tlns);
sender = window.sender = window.initSender();
var clazz = this.require(msg.module)[msg.classname];
main = window.main = new clazz(sender);
}
};
})(this);
ace.define("ace/lib/oop", [], function (require, exports, module) {
"use strict";
exports.inherits = function (ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
exports.mixin = function (obj, mixin) {
for (var key in mixin) {
obj[key] = mixin[key];
}
return obj;
};
exports.implement = function (proto, mixin) {
exports.mixin(proto, mixin);
};
});
ace.define("ace/apply_delta", [], function (require, exports, module) {
"use strict";
function throwDeltaError(delta, errorText) {
console.log("Invalid Delta:", delta);
throw "Invalid Delta: " + errorText;
}
function positionInDocument(docLines, position) {
return position.row >= 0 && position.row < docLines.length &&
position.column >= 0 && position.column <= docLines[position.row].length;
}
exports.applyDelta = function (docLines, delta, doNotValidate) {
var row = delta.start.row;
var startColumn = delta.start.column;
var line = docLines[row] || "";
switch (delta.action) {
case "insert":
var lines = delta.lines;
if (lines.length === 1) {
docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
}
else {
var args = [row, 1].concat(delta.lines);
docLines.splice.apply(docLines, args);
docLines[row] = line.substring(0, startColumn) + docLines[row];
docLines[row + delta.lines.length - 1] += line.substring(startColumn);
}
break;
case "remove":
var endColumn = delta.end.column;
var endRow = delta.end.row;
if (row === endRow) {
docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);
}
else {
docLines.splice(row, endRow - row + 1, line.substring(0, startColumn) + docLines[endRow].substring(endColumn));
}
break;
}
};
});
ace.define("ace/lib/event_emitter", [], function (require, exports, module) {
"use strict";
var EventEmitter = {};
class stopPropagation {
constructor() { this.propagationStopped = true; }
}
class preventDefault {
constructor() { this.defaultPrevented = true; }
}
EventEmitter._emit =
EventEmitter._dispatchEvent = function (eventName, e) {
this._eventRegistry || (this._eventRegistry = {});
this._defaultHandlers || (this._defaultHandlers = {});
var listeners = this._eventRegistry[eventName] || [];
var defaultHandler = this._defaultHandlers[eventName];
if (!listeners.length && !defaultHandler)
return;
if (typeof e != "object" || !e)
e = {};
if (!e.type)
e.type = eventName;
if (!e.stopPropagation)
e.stopPropagation = stopPropagation;
if (!e.preventDefault)
e.preventDefault = preventDefault;
listeners = listeners.slice();
for (var i = 0; i < listeners.length; i++) {
listeners[i](e, this);
if (e.propagationStopped)
break;
}
if (defaultHandler && !e.defaultPrevented)
return defaultHandler(e, this);
};
EventEmitter._signal = function (eventName, e) {
var listeners = (this._eventRegistry || {})[eventName];
if (!listeners)
return;
listeners = listeners.slice();
for (var i = 0; i < listeners.length; i++)
listeners[i](e, this);
};
EventEmitter.once = function (eventName, callback) {
var _self = this;
this.on(eventName, function newCallback() {
_self.off(eventName, newCallback);
callback.apply(null, arguments);
});
if (!callback) {
return new Promise(function (resolve) {
callback = resolve;
});
}
};
EventEmitter.setDefaultHandler = function (eventName, callback) {
var handlers = this._defaultHandlers;
if (!handlers)
handlers = this._defaultHandlers = { _disabled_: {} };
if (handlers[eventName]) {
var old = handlers[eventName];
var disabled = handlers._disabled_[eventName];
if (!disabled)
handlers._disabled_[eventName] = disabled = [];
disabled.push(old);
var i = disabled.indexOf(callback);
if (i != -1)
disabled.splice(i, 1);
}
handlers[eventName] = callback;
};
EventEmitter.removeDefaultHandler = function (eventName, callback) {
var handlers = this._defaultHandlers;
if (!handlers)
return;
var disabled = handlers._disabled_[eventName];
if (handlers[eventName] == callback) {
if (disabled)
this.setDefaultHandler(eventName, disabled.pop());
}
else if (disabled) {
var i = disabled.indexOf(callback);
if (i != -1)
disabled.splice(i, 1);
}
};
EventEmitter.on =
EventEmitter.addEventListener = function (eventName, callback, capturing) {
this._eventRegistry = this._eventRegistry || {};
var listeners = this._eventRegistry[eventName];
if (!listeners)
listeners = this._eventRegistry[eventName] = [];
if (listeners.indexOf(callback) == -1)
listeners[capturing ? "unshift" : "push"](callback);
return callback;
};
EventEmitter.off =
EventEmitter.removeListener =
EventEmitter.removeEventListener = function (eventName, callback) {
this._eventRegistry = this._eventRegistry || {};
var listeners = this._eventRegistry[eventName];
if (!listeners)
return;
var index = listeners.indexOf(callback);
if (index !== -1)
listeners.splice(index, 1);
};
EventEmitter.removeAllListeners = function (eventName) {
if (!eventName)
this._eventRegistry = this._defaultHandlers = undefined;
if (this._eventRegistry)
this._eventRegistry[eventName] = undefined;
if (this._defaultHandlers)
this._defaultHandlers[eventName] = undefined;
};
exports.EventEmitter = EventEmitter;
});
ace.define("ace/range", [], function (require, exports, module) {
"use strict";
var Range = /** @class */ (function () {
class Range {
constructor(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
column: startColumn
};
this.end = {
row: endRow,
column: endColumn
};
}
isEqual(range) {
return this.start.row === range.start.row &&
this.end.row === range.end.row &&
this.start.column === range.start.column &&
this.end.column === range.end.column;
}
toString() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
}
contains(row, column) {
return this.compare(row, column) == 0;
}
compareRange(range) {
var cmp, end = range.end, start = range.start;
cmp = this.compare(end.row, end.column);
if (cmp == 1) {
cmp = this.compare(start.row, start.column);
if (cmp == 1) {
return 2;
}
else if (cmp == 0) {
return 1;
}
else {
return 0;
}
}
else if (cmp == -1) {
return -2;
}
else {
cmp = this.compare(start.row, start.column);
if (cmp == -1) {
return -1;
}
else if (cmp == 1) {
return 42;
}
else {
return 0;
}
}
}
comparePoint(p) {
return this.compare(p.row, p.column);
}
containsRange(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
intersects(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
isEnd(row, column) {
return this.end.row == row && this.end.column == column;
}
isStart(row, column) {
return this.start.row == row && this.start.column == column;
}
setStart(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
this.start.row = row.row;
}
else {
this.start.row = row;
this.start.column = column;
}
}
setEnd(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
this.end.row = row.row;
}
else {
this.end.row = row;
this.end.column = column;
}
}
inside(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
return false;
}
else {
return true;
}
}
return false;
}
insideStart(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
return false;
}
else {
return true;
}
}
return false;
}
insideEnd(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
return false;
}
else {
return true;
}
}
return false;
}
compare(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
}
}
if (row < this.start.row)
return -1;
if (row > this.end.row)
return 1;
if (this.start.row === row)
return column >= this.start.column ? 0 : -1;
if (this.end.row === row)
return column <= this.end.column ? 0 : 1;
return 0;
}
compareStart(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
}
else {
return this.compare(row, column);
}
}
compareEnd(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
}
else {
return this.compare(row, column);
}
}
compareInside(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
}
else if (this.start.row == row && this.start.column == column) {
return -1;
}
else {
return this.compare(row, column);
}
}
clipRows(firstRow, lastRow) {
if (this.end.row > lastRow)
var end = { row: lastRow + 1, column: 0 };
else if (this.end.row < firstRow)
var end = { row: firstRow, column: 0 };
if (this.start.row > lastRow)
var start = { row: lastRow + 1, column: 0 };
else if (this.start.row < firstRow)
var start = { row: firstRow, column: 0 };
return Range.fromPoints(start || this.start, end || this.end);
}
extend(row, column) {
var cmp = this.compare(row, column);
if (cmp == 0)
return this;
else if (cmp == -1)
var start = { row: row, column: column };
else
var end = { row: row, column: column };
return Range.fromPoints(start || this.start, end || this.end);
}
isEmpty() {
return (this.start.row === this.end.row && this.start.column === this.end.column);
}
isMultiLine() {
return (this.start.row !== this.end.row);
}
clone() {
return Range.fromPoints(this.start, this.end);
}
collapseRows() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row - 1), 0);
else
return new Range(this.start.row, 0, this.end.row, 0);
}
toScreenRange(session) {
var screenPosStart = session.documentToScreenPosition(this.start);
var screenPosEnd = session.documentToScreenPosition(this.end);
return new Range(screenPosStart.row, screenPosStart.column, screenPosEnd.row, screenPosEnd.column);
}
moveBy(row, column) {
this.start.row += row;
this.start.column += column;
this.end.row += row;
this.end.column += column;
}
}
return Range;
}());
Range.fromPoints = function (start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
Range.comparePoints = function (p1, p2) {
return p1.row - p2.row || p1.column - p2.column;
};
exports.Range = Range;
});
ace.define("ace/anchor", [], function (require, exports, module) {
"use strict";
var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Anchor = /** @class */ (function () {
class Anchor {
constructor(doc, row, column) {
this.$onChange = this.onChange.bind(this);
this.attach(doc);
if (typeof row != "number")
this.setPosition(row.row, row.column);
else
this.setPosition(row, column);
}
getPosition() {
return this.$clipPositionToDocument(this.row, this.column);
}
getDocument() {
return this.document;
}
onChange(delta) {
if (delta.start.row == delta.end.row && delta.start.row != this.row)
return;
if (delta.start.row > this.row)
return;
var point = $getTransformedPoint(delta, { row: this.row, column: this.column }, this.$insertRight);
this.setPosition(point.row, point.column, true);
}
setPosition(row, column, noClip) {
var pos;
if (noClip) {
pos = {
row: row,
column: column
};
}
else {
pos = this.$clipPositionToDocument(row, column);
}
if (this.row == pos.row && this.column == pos.column)
return;
var old = {
row: this.row,
column: this.column
};
this.row = pos.row;
this.column = pos.column;
this._signal("change", {
old: old,
value: pos
});
}
detach() {
this.document.off("change", this.$onChange);
}
attach(doc) {
this.document = doc || this.document;
this.document.on("change", this.$onChange);
}
$clipPositionToDocument(row, column) {
var pos = {};
if (row >= this.document.getLength()) {
pos.row = Math.max(0, this.document.getLength() - 1);
pos.column = this.document.getLine(pos.row).length;
}
else if (row < 0) {
pos.row = 0;
pos.column = 0;
}
else {
pos.row = row;
pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
}
if (column < 0)
pos.column = 0;
return pos;
}
}
return Anchor;
}());
Anchor.prototype.$insertRight = false;
oop.implement(Anchor.prototype, EventEmitter);
function $pointsInOrder(point1, point2, equalPointsInOrder) {
var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;
return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);
}
function $getTransformedPoint(delta, point, moveIfEqual) {
var deltaIsInsert = delta.action == "insert";
var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row);
var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);
var deltaStart = delta.start;
var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.
if ($pointsInOrder(point, deltaStart, moveIfEqual)) {
return {
row: point.row,
column: point.column
};
}
if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {
return {
row: point.row + deltaRowShift,
column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)
};
}
return {
row: deltaStart.row,
column: deltaStart.column
};
}
exports.Anchor = Anchor;
});
ace.define("ace/document", [], function (require, exports, module) {
"use strict";
var oop = require("./lib/oop");
var applyDelta = require("./apply_delta").applyDelta;
var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
var Document = /** @class */ (function () {
function Document(textOrLines) {
this.$lines = [""];
if (textOrLines.length === 0) {
this.$lines = [""];
}
else if (Array.isArray(textOrLines)) {
this.insertMergedLines({ row: 0, column: 0 }, textOrLines);
}
else {
this.insert({ row: 0, column: 0 }, textOrLines);
}
}
Document.prototype.setValue = function (text) {
var len = this.getLength() - 1;
this.remove(new Range(0, 0, len, this.getLine(len).length));
this.insert({ row: 0, column: 0 }, text || "");
};
Document.prototype.getValue = function () {
return this.getAllLines().join(this.getNewLineCharacter());
};
Document.prototype.createAnchor = function (row, column) {
return new Anchor(this, row, column);
};
Document.prototype.$detectNewLine = function (text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
this.$autoNewLine = match ? match[1] : "\n";
this._signal("changeNewLineMode");
};
Document.prototype.getNewLineCharacter = function () {
switch (this.$newLineMode) {
case "windows":
return "\r\n";
case "unix":
return "\n";
default:
return this.$autoNewLine || "\n";
}
};
Document.prototype.setNewLineMode = function (newLineMode) {
if (this.$newLineMode === newLineMode)
return;
this.$newLineMode = newLineMode;
this._signal("changeNewLineMode");
};
Document.prototype.getNewLineMode = function () {
return this.$newLineMode;
};
Document.prototype.isNewLine = function (text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
Document.prototype.getLine = function (row) {
return this.$lines[row] || "";
};
Document.prototype.getLines = function (firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
Document.prototype.getAllLines = function () {
return this.getLines(0, this.getLength());
};
Document.prototype.getLength = function () {
return this.$lines.length;
};
Document.prototype.getTextRange = function (range) {
return this.getLinesForRange(range).join(this.getNewLineCharacter());
};
Document.prototype.getLinesForRange = function (range) {
var lines;
if (range.start.row === range.end.row) {
lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];
}
else {
lines = this.getLines(range.start.row, range.end.row);
lines[0] = (lines[0] || "").substring(range.start.column);
var l = lines.length - 1;
if (range.end.row - range.start.row == l)
lines[l] = lines[l].substring(0, range.end.column);
}
return lines;
};
Document.prototype.insertLines = function (row, lines) {
console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead.");
return this.insertFullLines(row, lines);
};
Document.prototype.removeLines = function (firstRow, lastRow) {
console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead.");
return this.removeFullLines(firstRow, lastRow);
};
Document.prototype.insertNewLine = function (position) {
console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.");
return this.insertMergedLines(position, ["", ""]);
};
Document.prototype.insert = function (position, text) {
if (this.getLength() <= 1)
this.$detectNewLine(text);
return this.insertMergedLines(position, this.$split(text));
};
Document.prototype.insertInLine = function (position, text) {
var start = this.clippedPos(position.row, position.column);
var end = this.pos(position.row, position.column + text.length);
this.applyDelta({
start: start,
end: end,
action: "insert",
lines: [text]
}, true);
return this.clonePos(end);
};
Document.prototype.clippedPos = function (row, column) {
var length = this.getLength();
if (row === undefined) {
row = length;
}
else if (row < 0) {
row = 0;
}
else if (row >= length) {
row = length - 1;
column = undefined;
}
var line = this.getLine(row);
if (column == undefined)
column = line.length;
column = Math.min(Math.max(column, 0), line.length);
return { row: row, column: column };
};
Document.prototype.clonePos = function (pos) {
return { row: pos.row, column: pos.column };
};
Document.prototype.pos = function (row, column) {
return { row: row, column: column };
};
Document.prototype.$clipPosition = function (position) {
var length = this.getLength();
if (position.row >= length) {
position.row = Math.max(0, length - 1);
position.column = this.getLine(length - 1).length;
}
else {
position.row = Math.max(0, position.row);
position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);
}
return position;
};
Document.prototype.insertFullLines = function (row, lines) {
row = Math.min(Math.max(row, 0), this.getLength());
var column = 0;
if (row < this.getLength()) {
lines = lines.concat([""]);
column = 0;
}
else {
lines = [""].concat(lines);
row--;
column = this.$lines[row].length;
}
this.insertMergedLines({ row: row, column: column }, lines);
};
Document.prototype.insertMergedLines = function (position, lines) {
var start = this.clippedPos(position.row, position.column);
var end = {
row: start.row + lines.length - 1,
column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length
};
this.applyDelta({
start: start,
end: end,
action: "insert",
lines: lines
});
return this.clonePos(end);
};
Document.prototype.remove = function (range) {
var start = this.clippedPos(range.start.row, range.start.column);
var end = this.clippedPos(range.end.row, range.end.column);
this.applyDelta({
start: start,
end: end,
action: "remove",
lines: this.getLinesForRange({ start: start, end: end })
});
return this.clonePos(start);
};
Document.prototype.removeInLine = function (row, startColumn, endColumn) {
var start = this.clippedPos(row, startColumn);
var end = this.clippedPos(row, endColumn);
this.applyDelta({
start: start,
end: end,
action: "remove",
lines: this.getLinesForRange({ start: start, end: end })
}, true);
return this.clonePos(start);
};
Document.prototype.removeFullLines = function (firstRow, lastRow) {
firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);
lastRow = Math.min(Math.max(0, lastRow), this.getLength() - 1);
var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;
var deleteLastNewLine = lastRow < this.getLength() - 1;
var startRow = (deleteFirstNewLine ? firstRow - 1 : firstRow);
var startCol = (deleteFirstNewLine ? this.getLine(startRow).length : 0);
var endRow = (deleteLastNewLine ? lastRow + 1 : lastRow);
var endCol = (deleteLastNewLine ? 0 : this.getLine(endRow).length);
var range = new Range(startRow, startCol, endRow, endCol);
var deletedLines = this.$lines.slice(firstRow, lastRow + 1);
this.applyDelta({
start: range.start,
end: range.end,
action: "remove",
lines: this.getLinesForRange(range)
});
return deletedLines;
};
Document.prototype.removeNewLine = function (row) {
if (row < this.getLength() - 1 && row >= 0) {
this.applyDelta({
start: this.pos(row, this.getLine(row).length),
end: this.pos(row + 1, 0),
action: "remove",
lines: ["", ""]
});
}
};
Document.prototype.replace = function (range, text) {
if (!(range instanceof Range))
range = Range.fromPoints(range.start, range.end);
if (text.length === 0 && range.isEmpty())
return range.start;
if (text == this.getTextRange(range))
return range.end;
this.remove(range);
var end;
if (text) {
end = this.insert(range.start, text);
}
else {
end = range.start;
}
return end;
};
Document.prototype.applyDeltas = function (deltas) {
for (var i = 0; i < deltas.length; i++) {
this.applyDelta(deltas[i]);
}
};
Document.prototype.revertDeltas = function (deltas) {
for (var i = deltas.length - 1; i >= 0; i--) {
this.revertDelta(deltas[i]);
}
};
Document.prototype.applyDelta = function (delta, doNotValidate) {
var isInsert = delta.action == "insert";
if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]
: !Range.comparePoints(delta.start, delta.end)) {
return;
}
if (isInsert && delta.lines.length > 20000) {
this.$splitAndapplyLargeDelta(delta, 20000);
}
else {
applyDelta(this.$lines, delta, doNotValidate);
this._signal("change", delta);
}
};
Document.prototype.$safeApplyDelta = function (delta) {
var docLength = this.$lines.length;
if (delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength
|| delta.action == "insert" && delta.start.row <= docLength) {
this.applyDelta(delta);
}
};
Document.prototype.$splitAndapplyLargeDelta = function (delta, MAX) {
var lines = delta.lines;
var l = lines.length - MAX + 1;
var row = delta.start.row;
var column = delta.start.column;
for (var from = 0, to = 0; from < l; from = to) {
to += MAX - 1;
var chunk = lines.slice(from, to);
chunk.push("");
this.applyDelta({
start: this.pos(row + from, column),
end: this.pos(row + to, column = 0),
action: delta.action,
lines: chunk
}, true);
}
delta.lines = lines.slice(from);
delta.start.row = row + from;
delta.start.column = column;
this.applyDelta(delta, true);
};
Document.prototype.revertDelta = function (delta) {
this.$safeApplyDelta({
start: this.clonePos(delta.start),
end: this.clonePos(delta.end),
action: (delta.action == "insert" ? "remove" : "insert"),
lines: delta.lines.slice()
});
};
Document.prototype.indexToPosition = function (index, startRow) {
var lines = this.$lines || this.getAllLines();
var newlineLength = this.getNewLineCharacter().length;
for (var i = startRow || 0, l = lines.length; i < l; i++) {
index -= lines[i].length + newlineLength;
if (index < 0)
return { row: i, column: index + lines[i].length + newlineLength };
}
return { row: l - 1, column: index + lines[l - 1].length + newlineLength };
};
Document.prototype.positionToIndex = function (pos, startRow) {
var lines = this.$lines || this.getAllLines();
var newlineLength = this.getNewLineCharacter().length;
var index = 0;
var row = Math.min(pos.row, lines.length);
for (var i = startRow || 0; i < row; ++i)
index += lines[i].length + newlineLength;
return index + pos.column;
};
Document.prototype.$split = function (text) {
return text.split(/\r\n|\r|\n/);
};
return Document;
}());
Document.prototype.$autoNewLine = "";
Document.prototype.$newLineMode = "auto";
oop.implement(Document.prototype, EventEmitter);
exports.Document = Document;
});
ace.define("ace/lib/deep_copy", [], function (require, exports, module) {
exports.deepCopy = function deepCopy(obj) {
if (typeof obj !== "object" || !obj)
return obj;
var copy;
if (Array.isArray(obj)) {
copy = [];
for (var key = 0; key < obj.length; key++) {
copy[key] = deepCopy(obj[key]);
}
return copy;
}
if (Object.prototype.toString.call(obj) !== "[object Object]")
return obj;
copy = {};
for (var key in obj)
copy[key] = deepCopy(obj[key]);
return copy;
};
});
ace.define("ace/lib/lang", [], function (require, exports, module) {
"use strict";
exports.last = function (a) {
return a[a.length - 1];
};
exports.stringReverse = function (string) {
return string.split("").reverse().join("");
};
exports.stringRepeat = function (string, count) {
var result = '';
while (count > 0) {
if (count & 1)
result += string;
if (count >>= 1)
string += string;
}
return result;
};
var trimBeginRegexp = /^\s\s*/;
var trimEndRegexp = /\s\s*$/;
exports.stringTrimLeft = function (string) {
return string.replace(trimBeginRegexp, '');
};
exports.stringTrimRight = function (string) {
return string.replace(trimEndRegexp, '');
};
exports.copyObject = function (obj) {
var copy = {};
for (var key in obj) {
copy[key] = obj[key];
}
return copy;
};
exports.copyArray = function (array) {
var copy = [];
for (var i = 0, l = array.length; i < l; i++) {
if (array[i] && typeof array[i] == "object")
copy[i] = this.copyObject(array[i]);
else
copy[i] = array[i];
}
return copy;
};
exports.deepCopy = require("./deep_copy").deepCopy;
exports.arrayToMap = function (arr) {
var map = {};
for (var i = 0; i < arr.length; i++) {
map[arr[i]] = 1;
}
return map;
};
exports.createMap = function (props) {
var map = Object.create(null);
for (var i in props) {
map[i] = props[i];
}
return map;
};
exports.arrayRemove = function (array, value) {
for (var i = 0; i <= array.length; i++) {
if (value === array[i]) {
array.splice(i, 1);
}
}
};
exports.escapeRegExp = function (str) {
return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
};
exports.escapeHTML = function (str) {
return ("" + str).replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
};
exports.getMatchOffsets = function (string, regExp) {
var matches = [];
string.replace(regExp, function (str) {
matches.push({
offset: arguments[arguments.length - 2],
length: str.length
});
});
return matches;
};
exports.deferredCall = function (fcn) {
var timer = null;
var callback = function () {
timer = null;
fcn();
};
var deferred = function (timeout) {
deferred.cancel();
timer = setTimeout(callback, timeout || 0);
return deferred;
};
deferred.schedule = deferred;
deferred.call = function () {
this.cancel();
fcn();
return deferred;
};
deferred.cancel = function () {
clearTimeout(timer);
timer = null;
return deferred;
};
deferred.isPending = function () {
return timer;
};
return deferred;
};
exports.delayedCall = function (fcn, defaultTimeout) {
var timer = null;
var callback = function () {
timer = null;
fcn();
};
var _self = function (timeout) {
if (timer == null)
timer = setTimeout(callback, timeout || defaultTimeout);
};
_self.delay = function (timeout) {
timer && clearTimeout(timer);
timer = setTimeout(callback, timeout || defaultTimeout);
};
_self.schedule = _self;
_self.call = function () {
this.cancel();
fcn();
};
_self.cancel = function () {
timer && clearTimeout(timer);
timer = null;
};
_self.isPending = function () {
return timer;
};
return _self;
};
exports.supportsLookbehind = function () {
try {
new RegExp('(?<=.)');
}
catch (e) {
return false;
}
return true;
};
exports.skipEmptyMatch = function (line, last, supportsUnicodeFlag) {
return supportsUnicodeFlag && line.codePointAt(last) > 0xffff ? 2 : 1;
};
});
ace.define("ace/worker/mirror", [], function (require, exports, module) {
"use strict";
var Document = require("../document").Document;
var lang = require("../lib/lang");
var Mirror = exports.Mirror = function (sender) {
this.sender = sender;
var doc = this.doc = new Document("");
var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
var _self = this;
sender.on("change", function (e) {
var data = e.data;
if (data[0].start) {
doc.applyDeltas(data);
} else {
for (var i = 0; i < data.length; i += 2) {
var d, err;
if (Array.isArray(data[i + 1])) {
d = { action: "insert", start: data[i], lines: data[i + 1] };
} else {
d = { action: "remove", start: data[i], end: data[i + 1] };
}
if ((d.action == "insert" ? d.start : d.end).row >= doc.$lines.length) {
err = new Error("Invalid delta");
err.data = {
path: _self.$path,
linesLength: doc.$lines.length,
start: d.start,
end: d.end
};
throw err;
}
doc.applyDelta(d, true);
}
}
if (_self.$timeout)
return deferredUpdate.schedule(_self.$timeout);
_self.onUpdate();
});
};
(function () {
this.$timeout = 500;
this.setTimeout = function (timeout) {
this.$timeout = timeout;
};
this.setValue = function (value) {
this.doc.setValue(value);
this.deferredUpdate.schedule(this.$timeout);
};
this.getValue = function (callbackId) {
this.sender.callback(this.doc.getValue(), callbackId);
};
this.onUpdate = function () {
};
this.isPending = function () {
return this.deferredUpdate.isPending();
};
}).call(Mirror.prototype);
});
ace.define("ace/mode/toml/toml_parse", [], function (require, exports, module) {
'use strict'
const ParserEND = 0x110000
class ParserError extends Error {
/* istanbul ignore next */
constructor(msg, filename, linenumber) {
super('[ParserError] ' + msg, filename, linenumber)
this.name = 'ParserError'
this.code = 'ParserError'
if (Error.captureStackTrace) Error.captureStackTrace(this, ParserError)
}
}
class State {
constructor(parser) {
this.parser = parser
this.buf = ''
this.returned = null
this.result = null
this.resultTable = null
this.resultArr = null
}
}
class Parser {
constructor() {
this.pos = 0
this.col = 0
this.line = 0
this.obj = {}
this.ctx = this.obj
this.stack = []
this._buf = ''
this.char = null
this.ii = 0
this.state = new State(this.parseStart)
}
parse(str) {
/* istanbul ignore next */
if (str.length === 0 || str.length == null) return
this._buf = String(str)
this.ii = -1
this.char = -1
let getNext
while (getNext === false || this.nextChar()) {
getNext = this.runOne()
}
this._buf = null
}
nextChar() {
if (this.char === 0x0A) {
++this.line
this.col = -1
}
++this.ii
this.char = this._buf.codePointAt(this.ii)
++this.pos
++this.col
return this.haveBuffer()
}
haveBuffer() {
return this.ii < this._buf.length
}
runOne() {
return this.state.parser.call(this, this.state.returned)
}
finish() {
this.char = ParserEND
let last
do {
last = this.state.parser
this.runOne()
} while (this.state.parser !== last)
this.ctx = null
this.state = null
this._buf = null
return this.obj
}
next(fn) {
/* istanbul ignore next */
if (typeof fn !== 'function') throw new ParserError('Tried to set state to non-existent state: ' + JSON.stringify(fn))
this.state.parser = fn
}
goto(fn) {
this.next(fn)
return this.runOne()
}
call(fn, returnWith) {
if (returnWith) this.next(returnWith)
this.stack.push(this.state)
this.state = new State(fn)
}
callNow(fn, returnWith) {
this.call(fn, returnWith)
return this.runOne()
}
return(value) {
/* istanbul ignore next */
if (this.stack.length === 0) throw this.error(new ParserError('Stack underflow'))
if (value === undefined) value = this.state.buf
this.state = this.stack.pop()
this.state.returned = value
}
returnNow(value) {
this.return(value)
return this.runOne()
}
consume() {
/* istanbul ignore next */
if (this.char === ParserEND) throw this.error(new ParserError('Unexpected end-of-buffer'))
this.state.buf += this._buf[this.ii]
}
error(err) {
err.line = this.line
err.col = this.col
err.pos = this.pos
return err
}
/* istanbul ignore next */
parseStart() {
throw new ParserError('Must declare a parseStart method')
}
}
Parser.END = ParserEND
Parser.Error = ParserError
function f(d, num) {
num = String(num)
while (num.length < d) num = '0' + num
return num
}
class TomlError extends Error {
constructor(msg) {
super(msg)
this.name = 'TomlError'
/* istanbul ignore next */
if (Error.captureStackTrace) Error.captureStackTrace(this, TomlError)
this.fromTOML = true
this.wrapped = null
}
}
TomlError.wrap = err => {
const terr = new TomlError(err.message)
terr.code = err.code
terr.wrapped = err
return terr
}
const createDateTime = value => {
const date = new Date(value)
/* istanbul ignore if */
if (isNaN(date)) {
throw new TypeError('Invalid Datetime')
} else {
return date
}
}
class FloatingDateTime extends Date {
constructor(value) {
super(value + 'Z')
this.isFloating = true
}
toISOString() {
const date = `${this.getUTCFullYear()}-${f(2, this.getUTCMonth() + 1)}-${f(2, this.getUTCDate())}`
const time = `${f(2, this.getUTCHours())}:${f(2, this.getUTCMinutes())}:${f(2, this.getUTCSeconds())}.${f(3, this.getUTCMilliseconds())}`
return `${date}T${time}`
}
}
const createDateTimeFloat = value => {
const date = new FloatingDateTime(value)
/* istanbul ignore if */
if (isNaN(date)) {
throw new TypeError('Invalid Datetime')
} else {
return date
}
}
class NewDate extends Date {
constructor(value) {
super(value)
this.isDate = true
}
toISOString() {
return `${this.getUTCFullYear()}-${f(2, this.getUTCMonth() + 1)}-${f(2, this.getUTCDate())}`
}
}
const createDate = value => {
const date = new NewDate(value)
/* istanbul ignore if */
if (isNaN(date)) {
throw new TypeError('Invalid Datetime')
} else {
return date
}
}
class Time extends Date {
constructor(value) {
super(`0000-01-01T${value}Z`)
this.isTime = true
}
toISOString() {
return `${f(2, this.getUTCHours())}:${f(2, this.getUTCMinutes())}:${f(2, this.getUTCSeconds())}.${f(3, this.getUTCMilliseconds())}`
}
}
const createTime = value => {
const date = new Time(value)
/* istanbul ignore if */
if (isNaN(date)) {
throw new TypeError('Invalid Datetime')
} else {
return date
}
}
const CTRL_I = 0x09
const CTRL_J = 0x0A
const CTRL_M = 0x0D
const CTRL_CHAR_BOUNDARY = 0x1F // the last non-character in the latin1 region of unicode, except DEL
const CHAR_SP = 0x20
const CHAR_QUOT = 0x22
const CHAR_NUM = 0x23
const CHAR_APOS = 0x27
const CHAR_PLUS = 0x2B
const CHAR_COMMA = 0x2C
const CHAR_HYPHEN = 0x2D
const CHAR_PERIOD = 0x2E
const CHAR_0 = 0x30
const CHAR_1 = 0x31
const CHAR_7 = 0x37
const CHAR_9 = 0x39
const CHAR_COLON = 0x3A
const CHAR_EQUALS = 0x3D
const CHAR_A = 0x41
const CHAR_E = 0x45
const CHAR_F = 0x46
const CHAR_T = 0x54
const CHAR_U = 0x55
const CHAR_Z = 0x5A
const CHAR_LOWBAR = 0x5F
const CHAR_a = 0x61
const CHAR_b = 0x62
const CHAR_e = 0x65
const CHAR_f = 0x66
const CHAR_i = 0x69
const CHAR_l = 0x6C
const CHAR_n = 0x6E
const CHAR_o = 0x6F
const CHAR_r = 0x72
const CHAR_s = 0x73
const CHAR_t = 0x74
const CHAR_u = 0x75
const CHAR_x = 0x78
const CHAR_z = 0x7A
const CHAR_LCUB = 0x7B
const CHAR_RCUB = 0x7D
const CHAR_LSQB = 0x5B
const CHAR_BSOL = 0x5C
const CHAR_RSQB = 0x5D
const CHAR_DEL = 0x7F
const SURROGATE_FIRST = 0xD800
const SURROGATE_LAST = 0xDFFF
const escapes = {
[CHAR_b]: '\u0008',
[CHAR_t]: '\u0009',
[CHAR_n]: '\u000A',
[CHAR_f]: '\u000C',
[CHAR_r]: '\u000D',
[CHAR_QUOT]: '\u0022',
[CHAR_BSOL]: '\u005C'
}
function isDigit(cp) {
return cp >= CHAR_0 && cp <= CHAR_9
}
function isHexit(cp) {
return (cp >= CHAR_A && cp <= CHAR_F) || (cp >= CHAR_a && cp <= CHAR_f) || (cp >= CHAR_0 && cp <= CHAR_9)
}
function isBit(cp) {
return cp === CHAR_1 || cp === CHAR_0
}
function isOctit(cp) {
return (cp >= CHAR_0 && cp <= CHAR_7)
}
function isAlphaNumQuoteHyphen(cp) {
return (cp >= CHAR_A && cp <= CHAR_Z)
|| (cp >= CHAR_a && cp <= CHAR_z)
|| (cp >= CHAR_0 && cp <= CHAR_9)
|| cp === CHAR_APOS
|| cp === CHAR_QUOT
|| cp === CHAR_LOWBAR
|| cp === CHAR_HYPHEN
}
function isAlphaNumHyphen(cp) {
return (cp >= CHAR_A && cp <= CHAR_Z)
|| (cp >= CHAR_a && cp <= CHAR_z)
|| (cp >= CHAR_0 && cp <= CHAR_9)
|| cp === CHAR_LOWBAR
|| cp === CHAR_HYPHEN
}
const _type = Symbol('type')
const _declared = Symbol('declared')
const hasOwnProperty = Object.prototype.hasOwnProperty
const defineProperty = Object.defineProperty
const descriptor = { configurable: true, enumerable: true, writable: true, value: undefined }
function hasKey(obj, key) {
if (hasOwnProperty.call(obj, key)) return true
if (key === '__proto__') defineProperty(obj, '__proto__', descriptor)
return false
}
const INLINE_TABLE = Symbol('inline-table')
function InlineTable() {
return Object.defineProperties({}, {
[_type]: { value: INLINE_TABLE }
})
}
function isInlineTable(obj) {
if (obj === null || typeof (obj) !== 'object') return false
return obj[_type] === INLINE_TABLE
}
const TABLE = Symbol('table')
function Table() {
return Object.defineProperties({}, {
[_type]: { value: TABLE },
[_declared]: { value: false, writable: true }
})
}
function isTable(obj) {
if (obj === null || typeof (obj) !== 'object') return false
return obj[_type] === TABLE
}
const _contentType = Symbol('content-type')
const INLINE_LIST = Symbol('inline-list')
function InlineList(type) {
return Object.defineProperties([], {
[_type]: { value: INLINE_LIST },
[_contentType]: { value: type }
})
}
function isInlineList(obj) {
if (obj === null || typeof (obj) !== 'object') return false
return obj[_type] === INLINE_LIST
}
const LIST = Symbol('list')
function List() {
return Object.defineProperties([], {
[_type]: { value: LIST }
})
}
function isList(obj) {
if (obj === null || typeof (obj) !== 'object') return false
return obj[_type] === LIST
}
// in an eval, to let bundlers not slurp in a util proxy
let _custom
try {
const utilInspect = eval("require('util').inspect")
_custom = utilInspect.custom
} catch (_) {
/* eval require not available in transpiled bundle */
}
/* istanbul ignore next */
const _inspect = _custom || 'inspect'
class BoxedBigInt {
constructor(value) {
try {
this.value = BigInt.asIntN(64, value)
} catch (_) {
/* istanbul ignore next */
this.value = null
}
Object.defineProperty(this, _type, { value: INTEGER })
}
isNaN() {
return this.value === null
}
/* istanbul ignore next */
toString() {
return String(this.value)
}
/* istanbul ignore next */
[_inspect]() {
return `[BigInt: ${this.toString()}]}`
}
valueOf() {
return this.value
}
}
const INTEGER = Symbol('integer')
function Integer(value) {
let num = Number(value)
// -0 is a float thing, not an int thing
if (Object.is(num, -0)) num = 0
/* istanbul ignore else */
if (BigInt && !Number.isSafeInteger(num)) {
return new BoxedBigInt(value)
} else {
/* istanbul ignore next */
return Object.defineProperties(new Number(num), {
isNaN: { value: function () { return isNaN(this) } },
[_type]: { value: INTEGER },
[_inspect]: { value: () => `[Integer: ${value}]` }
})
}
}
function isInteger(obj) {
if (obj === null || typeof (obj) !== 'object') return false
return obj[_type] === INTEGER
}
const FLOAT = Symbol('float')
function Float(value) {
/* istanbul ignore next */
return Object.defineProperties(new Number(value), {
[_type]: { value: FLOAT },
[_inspect]: { value: () => `[Float: ${value}]` }
})
}
function isFloat(obj) {
if (obj === null || typeof (obj) !== 'object') return false
return obj[_type] === FLOAT
}
function tomlType(value) {
const type = typeof value
if (type === 'object') {
/* istanbul ignore if */
if (value === null) return 'null'
if (value instanceof Date) return 'datetime'
/* istanbul ignore else */
if (_type in value) {
switch (value[_type]) {
case INLINE_TABLE: return 'inline-table'
case INLINE_LIST: return 'inline-list'
/* istanbul ignore next */
case TABLE: return 'table'
/* istanbul ignore next */
case LIST: return 'list'
case FLOAT: return 'float'
case INTEGER: return 'integer'
}
}
}
return type
}
function makeParserClass(Parser) {
class TOMLParser extends Parser {
constructor() {
super()
this.ctx = this.obj = Table()
}
/* MATCH HELPER */
atEndOfWord() {
return this.char === CHAR_NUM || this.char === CTRL_I || this.char === CHAR_SP || this.atEndOfLine()
}
atEndOfLine() {
return this.char === Parser.END || this.char === CTRL_J || this.char === CTRL_M
}
parseStart() {
if (this.char === Parser.END) {
return null
} else if (this.char === CHAR_LSQB) {
return this.call(this.parseTableOrList)
} else if (this.char === CHAR_NUM) {
return this.call(this.parseComment)
} else if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
return null
} else if (isAlphaNumQuoteHyphen(this.char)) {
return this.callNow(this.parseAssignStatement)
} else {
throw this.error(new TomlError(`Unknown character "${this.char}"`))
}
}
// HELPER, this strips any whitespace and comments to the end of the line
// then RETURNS. Last state in a production.
parseWhitespaceToEOL() {
if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
return null
} else if (this.char === CHAR_NUM) {
return this.goto(this.parseComment)
} else if (this.char === Parser.END || this.char === CTRL_J) {
return this.return()
} else {
throw this.error(new TomlError('Unexpected character, expected only whitespace or comments till end of line'))
}
}
/* ASSIGNMENT: key = value */
parseAssignStatement() {
return this.callNow(this.parseAssign, this.recordAssignStatement)
}
recordAssignStatement(kv) {
let target = this.ctx
let finalKey = kv.key.pop()
for (let kw of kv.key) {
if (hasKey(target, kw) && !isTable(target[kw])) {
throw this.error(new TomlError("Can't redefine existing key"))
}
target = target[kw] = target[kw] || Table()
}
if (hasKey(target, finalKey)) {
throw this.error(new TomlError("Can't redefine existing key"))
}
target[_declared] = true
// unbox our numbers
if (isInteger(kv.value) || isFloat(kv.value)) {
target[finalKey] = kv.value.valueOf()
} else {
target[finalKey] = kv.value
}
return this.goto(this.parseWhitespaceToEOL)
}
/* ASSSIGNMENT expression, key = value possibly inside an inline table */
parseAssign() {
return this.callNow(this.parseKeyword, this.recordAssignKeyword)
}
recordAssignKeyword(key) {
if (this.state.resultTable) {
this.state.resultTable.push(key)
} else {
this.state.resultTable = [key]
}
return this.goto(this.parseAssignKeywordPreDot)
}
parseAssignKeywordPreDot() {
if (this.char === CHAR_PERIOD) {
return this.next(this.parseAssignKeywordPostDot)
} else if (this.char !== CHAR_SP && this.char !== CTRL_I) {
return this.goto(this.parseAssignEqual)
}
}
parseAssignKeywordPostDot() {
if (this.char !== CHAR_SP && this.char !== CTRL_I) {
return this.callNow(this.parseKeyword, this.recordAssignKeyword)
}
}
parseAssignEqual() {
if (this.char === CHAR_EQUALS) {
return this.next(this.parseAssignPreValue)
} else {
throw this.error(new TomlError('Invalid character, expected "="'))
}
}
parseAssignPreValue() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else {
return this.callNow(this.parseValue, this.recordAssignValue)
}
}
recordAssignValue(value) {
return this.returnNow({ key: this.state.resultTable, value: value })
}
/* COMMENTS: #...eol */
parseComment() {
do {
if (this.char === Parser.END || this.char === CTRL_J) {
return this.return()
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I)) {
throw this.errorControlCharIn('comments')
}
} while (this.nextChar())
}
/* TABLES AND LISTS, [foo] and [[foo]] */
parseTableOrList() {
if (this.char === CHAR_LSQB) {
this.next(this.parseList)
} else {
return this.goto(this.parseTable)
}
}
/* TABLE [foo.bar.baz] */
parseTable() {
this.ctx = this.obj
return this.goto(this.parseTableNext)
}
parseTableNext() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else {
return this.callNow(this.parseKeyword, this.parseTableMore)
}
}
parseTableMore(keyword) {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else if (this.char === CHAR_RSQB) {
if (hasKey(this.ctx, keyword) && (!isTable(this.ctx[keyword]) || this.ctx[keyword][_declared])) {
throw this.error(new TomlError("Can't redefine existing key"))
} else {
this.ctx = this.ctx[keyword] = this.ctx[keyword] || Table()
this.ctx[_declared] = true
}
return this.next(this.parseWhitespaceToEOL)
} else if (this.char === CHAR_PERIOD) {
if (!hasKey(this.ctx, keyword)) {
this.ctx = this.ctx[keyword] = Table()
} else if (isTable(this.ctx[keyword])) {
this.ctx = this.ctx[keyword]
} else if (isList(this.ctx[keyword])) {
this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1]
} else {
throw this.error(new TomlError("Can't redefine existing key"))
}
return this.next(this.parseTableNext)
} else {
throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]'))
}
}
/* LIST [[a.b.c]] */
parseList() {
this.ctx = this.obj
return this.goto(this.parseListNext)
}
parseListNext() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else {
return this.callNow(this.parseKeyword, this.parseListMore)
}
}
parseListMore(keyword) {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else if (this.char === CHAR_RSQB) {
if (!hasKey(this.ctx, keyword)) {
this.ctx[keyword] = List()
}
if (isInlineList(this.ctx[keyword])) {
throw this.error(new TomlError("Can't extend an inline array"))
} else if (isList(this.ctx[keyword])) {
const next = Table()
this.ctx[keyword].push(next)
this.ctx = next
} else {
throw this.error(new TomlError("Can't redefine an existing key"))
}
return this.next(this.parseListEnd)
} else if (this.char === CHAR_PERIOD) {
if (!hasKey(this.ctx, keyword)) {
this.ctx = this.ctx[keyword] = Table()
} else if (isInlineList(this.ctx[keyword])) {
throw this.error(new TomlError("Can't extend an inline array"))
} else if (isInlineTable(this.ctx[keyword])) {
throw this.error(new TomlError("Can't extend an inline table"))
} else if (isList(this.ctx[keyword])) {
this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1]
} else if (isTable(this.ctx[keyword])) {
this.ctx = this.ctx[keyword]
} else {
throw this.error(new TomlError("Can't redefine an existing key"))
}
return this.next(this.parseListNext)
} else {
throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]'))
}
}
parseListEnd(keyword) {
if (this.char === CHAR_RSQB) {
return this.next(this.parseWhitespaceToEOL)
} else {
throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]'))
}
}
/* VALUE string, number, boolean, inline list, inline object */
parseValue() {
if (this.char === Parser.END) {
throw this.error(new TomlError('Key without value'))
} else if (this.char === CHAR_QUOT) {
return this.next(this.parseDoubleString)
} if (this.char === CHAR_APOS) {
return this.next(this.parseSingleString)
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
return this.goto(this.parseNumberSign)
} else if (this.char === CHAR_i) {
return this.next(this.parseInf)
} else if (this.char === CHAR_n) {
return this.next(this.parseNan)
} else if (isDigit(this.char)) {
return this.goto(this.parseNumberOrDateTime)
} else if (this.char === CHAR_t || this.char === CHAR_f) {
return this.goto(this.parseBoolean)
} else if (this.char === CHAR_LSQB) {
return this.call(this.parseInlineList, this.recordValue)
} else if (this.char === CHAR_LCUB) {
return this.call(this.parseInlineTable, this.recordValue)
} else {
throw this.error(new TomlError('Unexpected character, expecting string, number, datetime, boolean, inline array or inline table'))
}
}
recordValue(value) {
return this.returnNow(value)
}
parseInf() {
if (this.char === CHAR_n) {
return this.next(this.parseInf2)
} else {
throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'))
}
}
parseInf2() {
if (this.char === CHAR_f) {
if (this.state.buf === '-') {
return this.return(-Infinity)
} else {
return this.return(Infinity)
}
} else {
throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'))
}
}
parseNan() {
if (this.char === CHAR_a) {
return this.next(this.parseNan2)
} else {
throw this.error(new TomlError('Unexpected character, expected "nan"'))
}
}
parseNan2() {
if (this.char === CHAR_n) {
return this.return(NaN)
} else {
throw this.error(new TomlError('Unexpected character, expected "nan"'))
}
}
/* KEYS, barewords or basic, literal, or dotted */
parseKeyword() {
if (this.char === CHAR_QUOT) {
return this.next(this.parseBasicString)
} else if (this.char === CHAR_APOS) {
return this.next(this.parseLiteralString)
} else {
return this.goto(this.parseBareKey)
}
}
/* KEYS: barewords */
parseBareKey() {
do {
if (this.char === Parser.END) {
throw this.error(new TomlError('Key ended without value'))
} else if (isAlphaNumHyphen(this.char)) {
this.consume()
} else if (this.state.buf.length === 0) {
throw this.error(new TomlError('Empty bare keys are not allowed'))
} else {
return this.returnNow()
}
} while (this.nextChar())
}
/* STRINGS, single quoted (literal) */
parseSingleString() {
if (this.char === CHAR_APOS) {
return this.next(this.parseLiteralMultiStringMaybe)
} else {
return this.goto(this.parseLiteralString)
}
}
parseLiteralString() {
do {
if (this.char === CHAR_APOS) {
return this.return()
} else if (this.atEndOfLine()) {
throw this.error(new TomlError('Unterminated string'))
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I)) {
throw this.errorControlCharIn('strings')
} else {
this.consume()
}
} while (this.nextChar())
}
parseLiteralMultiStringMaybe() {
if (this.char === CHAR_APOS) {
return this.next(this.parseLiteralMultiString)
} else {
return this.returnNow()
}
}
parseLiteralMultiString() {
if (this.char === CTRL_M) {
return null
} else if (this.char === CTRL_J) {
return this.next(this.parseLiteralMultiStringContent)
} else {
return this.goto(this.parseLiteralMultiStringContent)
}
}
parseLiteralMultiStringContent() {
do {
if (this.char === CHAR_APOS) {
return this.next(this.parseLiteralMultiEnd)
} else if (this.char === Parser.END) {
throw this.error(new TomlError('Unterminated multi-line string'))
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M)) {
throw this.errorControlCharIn('strings')
} else {
this.consume()
}
} while (this.nextChar())
}
parseLiteralMultiEnd() {
if (this.char === CHAR_APOS) {
return this.next(this.parseLiteralMultiEnd2)
} else {
this.state.buf += "'"
return this.goto(this.parseLiteralMultiStringContent)
}
}
parseLiteralMultiEnd2() {
if (this.char === CHAR_APOS) {
return this.next(this.parseLiteralMultiEnd3)
} else {
this.state.buf += "''"
return this.goto(this.parseLiteralMultiStringContent)
}
}
parseLiteralMultiEnd3() {
if (this.char === CHAR_APOS) {
this.state.buf += "'"
return this.next(this.parseLiteralMultiEnd4)
} else {
return this.returnNow()
}
}
parseLiteralMultiEnd4() {
if (this.char === CHAR_APOS) {
this.state.buf += "'"
return this.return()
} else {
return this.returnNow()
}
}
/* STRINGS double quoted */
parseDoubleString() {
if (this.char === CHAR_QUOT) {
return this.next(this.parseMultiStringMaybe)
} else {
return this.goto(this.parseBasicString)
}
}
parseBasicString() {
do {
if (this.char === CHAR_BSOL) {
return this.call(this.parseEscape, this.recordEscapeReplacement)
} else if (this.char === CHAR_QUOT) {
return this.return()
} else if (this.atEndOfLine()) {
throw this.error(new TomlError('Unterminated string'))
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I)) {
throw this.errorControlCharIn('strings')
} else {
this.consume()
}
} while (this.nextChar())
}
recordEscapeReplacement(replacement) {
this.state.buf += replacement
return this.goto(this.parseBasicString)
}
parseMultiStringMaybe() {
if (this.char === CHAR_QUOT) {
return this.next(this.parseMultiString)
} else {
return this.returnNow()
}
}
parseMultiString() {
if (this.char === CTRL_M) {
return null
} else if (this.char === CTRL_J) {
return this.next(this.parseMultiStringContent)
} else {
return this.goto(this.parseMultiStringContent)
}
}
parseMultiStringContent() {
do {
if (this.char === CHAR_BSOL) {
return this.call(this.parseMultiEscape, this.recordMultiEscapeReplacement)
} else if (this.char === CHAR_QUOT) {
return this.next(this.parseMultiEnd)
} else if (this.char === Parser.END) {
throw this.error(new TomlError('Unterminated multi-line string'))
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M)) {
throw this.errorControlCharIn('strings')
} else {
this.consume()
}
} while (this.nextChar())
}
errorControlCharIn(type) {
let displayCode = '\\u00'
if (this.char < 16) {
displayCode += '0'
}
displayCode += this.char.toString(16)
return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in ${type}, use ${displayCode} instead`))
}
recordMultiEscapeReplacement(replacement) {
this.state.buf += replacement
return this.goto(this.parseMultiStringContent)
}
parseMultiEnd() {
if (this.char === CHAR_QUOT) {
return this.next(this.parseMultiEnd2)
} else {
this.state.buf += '"'
return this.goto(this.parseMultiStringContent)
}
}
parseMultiEnd2() {
if (this.char === CHAR_QUOT) {
return this.next(this.parseMultiEnd3)
} else {
this.state.buf += '""'
return this.goto(this.parseMultiStringContent)
}
}
parseMultiEnd3() {
if (this.char === CHAR_QUOT) {
this.state.buf += '"'
return this.next(this.parseMultiEnd4)
} else {
return this.returnNow()
}
}
parseMultiEnd4() {
if (this.char === CHAR_QUOT) {
this.state.buf += '"'
return this.return()
} else {
return this.returnNow()
}
}
parseMultiEscape() {
if (this.char === CTRL_M || this.char === CTRL_J) {
return this.next(this.parseMultiTrim)
} else if (this.char === CHAR_SP || this.char === CTRL_I) {
return this.next(this.parsePreMultiTrim)
} else {
return this.goto(this.parseEscape)
}
}
parsePreMultiTrim() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else if (this.char === CTRL_M || this.char === CTRL_J) {
return this.next(this.parseMultiTrim)
} else {
throw this.error(new TomlError("Can't escape whitespace"))
}
}
parseMultiTrim() {
// explicitly whitespace here, END should follow the same path as chars
if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
return null
} else {
return this.returnNow()
}
}
parseEscape() {
if (this.char in escapes) {
return this.return(escapes[this.char])
} else if (this.char === CHAR_u) {
return this.call(this.parseSmallUnicode, this.parseUnicodeReturn)
} else if (this.char === CHAR_U) {
return this.call(this.parseLargeUnicode, this.parseUnicodeReturn)
} else {
throw this.error(new TomlError('Unknown escape character: ' + this.char))
}
}
parseUnicodeReturn(char) {
try {
const codePoint = parseInt(char, 16)
if (codePoint >= SURROGATE_FIRST && codePoint <= SURROGATE_LAST) {
throw this.error(new TomlError('Invalid unicode, character in range 0xD800 - 0xDFFF is reserved'))
}
return this.returnNow(String.fromCodePoint(codePoint))
} catch (err) {
throw this.error(TomlError.wrap(err))
}
}
parseSmallUnicode() {
if (!isHexit(this.char)) {
throw this.error(new TomlError('Invalid character in unicode sequence, expected hex'))
} else {
this.consume()
if (this.state.buf.length >= 4) return this.return()
}
}
parseLargeUnicode() {
if (!isHexit(this.char)) {
throw this.error(new TomlError('Invalid character in unicode sequence, expected hex'))
} else {
this.consume()
if (this.state.buf.length >= 8) return this.return()
}
}
/* NUMBERS */
parseNumberSign() {
this.consume()
return this.next(this.parseMaybeSignedInfOrNan)
}
parseMaybeSignedInfOrNan() {
if (this.char === CHAR_i) {
return this.next(this.parseInf)
} else if (this.char === CHAR_n) {
return this.next(this.parseNan)
} else {
return this.callNow(this.parseNoUnder, this.parseNumberIntegerStart)
}
}
parseNumberIntegerStart() {
if (this.char === CHAR_0) {
this.consume()
return this.next(this.parseNumberIntegerExponentOrDecimal)
} else {
return this.goto(this.parseNumberInteger)
}
}
parseNumberIntegerExponentOrDecimal() {
if (this.char === CHAR_PERIOD) {
this.consume()
return this.call(this.parseNoUnder, this.parseNumberFloat)
} else if (this.char === CHAR_E || this.char === CHAR_e) {
this.consume()
return this.next(this.parseNumberExponentSign)
} else {
return this.returnNow(Integer(this.state.buf))
}
}
parseNumberInteger() {
if (isDigit(this.char)) {
this.consume()
} else if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnder)
} else if (this.char === CHAR_E || this.char === CHAR_e) {
this.consume()
return this.next(this.parseNumberExponentSign)
} else if (this.char === CHAR_PERIOD) {
this.consume()
return this.call(this.parseNoUnder, this.parseNumberFloat)
} else {
const result = Integer(this.state.buf)
/* istanbul ignore if */
if (result.isNaN()) {
throw this.error(new TomlError('Invalid number'))
} else {
return this.returnNow(result)
}
}
}
parseNoUnder() {
if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD || this.char === CHAR_E || this.char === CHAR_e) {
throw this.error(new TomlError('Unexpected character, expected digit'))
} else if (this.atEndOfWord()) {
throw this.error(new TomlError('Incomplete number'))
}
return this.returnNow()
}
parseNoUnderHexOctBinLiteral() {
if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD) {
throw this.error(new TomlError('Unexpected character, expected digit'))
} else if (this.atEndOfWord()) {
throw this.error(new TomlError('Incomplete number'))
}
return this.returnNow()
}
parseNumberFloat() {
if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnder, this.parseNumberFloat)
} else if (isDigit(this.char)) {
this.consume()
} else if (this.char === CHAR_E || this.char === CHAR_e) {
this.consume()
return this.next(this.parseNumberExponentSign)
} else {
return this.returnNow(Float(this.state.buf))
}
}
parseNumberExponentSign() {
if (isDigit(this.char)) {
return this.goto(this.parseNumberExponent)
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
this.consume()
this.call(this.parseNoUnder, this.parseNumberExponent)
} else {
throw this.error(new TomlError('Unexpected character, expected -, + or digit'))
}
}
parseNumberExponent() {
if (isDigit(this.char)) {
this.consume()
} else if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnder)
} else {
return this.returnNow(Float(this.state.buf))
}
}
/* NUMBERS or DATETIMES */
parseNumberOrDateTime() {
if (this.char === CHAR_0) {
this.consume()
return this.next(this.parseNumberBaseOrDateTime)
} else {
return this.goto(this.parseNumberOrDateTimeOnly)
}
}
parseNumberOrDateTimeOnly() {
// note, if two zeros are in a row then it MUST be a date
if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnder, this.parseNumberInteger)
} else if (isDigit(this.char)) {
this.consume()
if (this.state.buf.length > 4) this.next(this.parseNumberInteger)
} else if (this.char === CHAR_E || this.char === CHAR_e) {
this.consume()
return this.next(this.parseNumberExponentSign)
} else if (this.char === CHAR_PERIOD) {
this.consume()
return this.call(this.parseNoUnder, this.parseNumberFloat)
} else if (this.char === CHAR_HYPHEN) {
return this.goto(this.parseDateTime)
} else if (this.char === CHAR_COLON) {
return this.goto(this.parseOnlyTimeHour)
} else {
return this.returnNow(Integer(this.state.buf))
}
}
parseDateTimeOnly() {
if (this.state.buf.length < 4) {
if (isDigit(this.char)) {
return this.consume()
} else if (this.char === CHAR_COLON) {
return this.goto(this.parseOnlyTimeHour)
} else {
throw this.error(new TomlError('Expected digit while parsing year part of a date'))
}
} else {
if (this.char === CHAR_HYPHEN) {
return this.goto(this.parseDateTime)
} else {
throw this.error(new TomlError('Expected hyphen (-) while parsing year part of date'))
}
}
}
parseNumberBaseOrDateTime() {
if (this.char === CHAR_b) {
this.consume()
return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerBin)
} else if (this.char === CHAR_o) {
this.consume()
return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerOct)
} else if (this.char === CHAR_x) {
this.consume()
return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerHex)
} else if (this.char === CHAR_PERIOD) {
return this.goto(this.parseNumberInteger)
} else if (isDigit(this.char)) {
return this.goto(this.parseDateTimeOnly)
} else {
return this.returnNow(Integer(this.state.buf))
}
}
parseIntegerHex() {
if (isHexit(this.char)) {
this.consume()
} else if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnderHexOctBinLiteral)
} else {
const result = Integer(this.state.buf)
/* istanbul ignore if */
if (result.isNaN()) {
throw this.error(new TomlError('Invalid number'))
} else {
return this.returnNow(result)
}
}
}
parseIntegerOct() {
if (isOctit(this.char)) {
this.consume()
} else if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnderHexOctBinLiteral)
} else {
const result = Integer(this.state.buf)
/* istanbul ignore if */
if (result.isNaN()) {
throw this.error(new TomlError('Invalid number'))
} else {
return this.returnNow(result)
}
}
}
parseIntegerBin() {
if (isBit(this.char)) {
this.consume()
} else if (this.char === CHAR_LOWBAR) {
return this.call(this.parseNoUnderHexOctBinLiteral)
} else {
const result = Integer(this.state.buf)
/* istanbul ignore if */
if (result.isNaN()) {
throw this.error(new TomlError('Invalid number'))
} else {
return this.returnNow(result)
}
}
}
/* DATETIME */
parseDateTime() {
// we enter here having just consumed the year and about to consume the hyphen
if (this.state.buf.length < 4) {
throw this.error(new TomlError('Years less than 1000 must be zero padded to four characters'))
}
this.state.result = this.state.buf
this.state.buf = ''
return this.next(this.parseDateMonth)
}
parseDateMonth() {
if (this.char === CHAR_HYPHEN) {
if (this.state.buf.length < 2) {
throw this.error(new TomlError('Months less than 10 must be zero padded to two characters'))
}
this.state.result += '-' + this.state.buf
this.state.buf = ''
return this.next(this.parseDateDay)
} else if (isDigit(this.char)) {
this.consume()
} else {
throw this.error(new TomlError('Incomplete datetime'))
}
}
parseDateDay() {
if (this.char === CHAR_T || this.char === CHAR_SP) {
if (this.state.buf.length < 2) {
throw this.error(new TomlError('Days less than 10 must be zero padded to two characters'))
}
this.state.result += '-' + this.state.buf
this.state.buf = ''
return this.next(this.parseStartTimeHour)
} else if (this.atEndOfWord()) {
return this.returnNow(createDate(this.state.result + '-' + this.state.buf))
} else if (isDigit(this.char)) {
this.consume()
} else {
throw this.error(new TomlError('Incomplete datetime'))
}
}
parseStartTimeHour() {
if (this.atEndOfWord()) {
return this.returnNow(createDate(this.state.result))
} else {
return this.goto(this.parseTimeHour)
}
}
parseTimeHour() {
if (this.char === CHAR_COLON) {
if (this.state.buf.length < 2) {
throw this.error(new TomlError('Hours less than 10 must be zero padded to two characters'))
}
this.state.result += 'T' + this.state.buf
this.state.buf = ''
return this.next(this.parseTimeMin)
} else if (isDigit(this.char)) {
this.consume()
} else {
throw this.error(new TomlError('Incomplete datetime'))
}
}
parseTimeMin() {
if (this.state.buf.length < 2 && isDigit(this.char)) {
this.consume()
} else if (this.state.buf.length === 2 && this.char === CHAR_COLON) {
this.state.result += ':' + this.state.buf
this.state.buf = ''
return this.next(this.parseTimeSec)
} else {
throw this.error(new TomlError('Incomplete datetime'))
}
}
parseTimeSec() {
if (isDigit(this.char)) {
this.consume()
if (this.state.buf.length === 2) {
this.state.result += ':' + this.state.buf
this.state.buf = ''
return this.next(this.parseTimeZoneOrFraction)
}
} else {
throw this.error(new TomlError('Incomplete datetime'))
}
}
parseOnlyTimeHour() {
/* istanbul ignore else */
if (this.char === CHAR_COLON) {
if (this.state.buf.length < 2) {
throw this.error(new TomlError('Hours less than 10 must be zero padded to two characters'))
}
this.state.result = this.state.buf
this.state.buf = ''
return this.next(this.parseOnlyTimeMin)
} else {
throw this.error(new TomlError('Incomplete time'))
}
}
parseOnlyTimeMin() {
if (this.state.buf.length < 2 && isDigit(this.char)) {
this.consume()
} else if (this.state.buf.length === 2 && this.char === CHAR_COLON) {
this.state.result += ':' + this.state.buf
this.state.buf = ''
return this.next(this.parseOnlyTimeSec)
} else {
throw this.error(new TomlError('Incomplete time'))
}
}
parseOnlyTimeSec() {
if (isDigit(this.char)) {
this.consume()
if (this.state.buf.length === 2) {
return this.next(this.parseOnlyTimeFractionMaybe)
}
} else {
throw this.error(new TomlError('Incomplete time'))
}
}
parseOnlyTimeFractionMaybe() {
this.state.result += ':' + this.state.buf
if (this.char === CHAR_PERIOD) {
this.state.buf = ''
this.next(this.parseOnlyTimeFraction)
} else {
return this.return(createTime(this.state.result))
}
}
parseOnlyTimeFraction() {
if (isDigit(this.char)) {
this.consume()
} else if (this.atEndOfWord()) {
if (this.state.buf.length === 0) throw this.error(new TomlError('Expected digit in milliseconds'))
return this.returnNow(createTime(this.state.result + '.' + this.state.buf))
} else {
throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z'))
}
}
parseTimeZoneOrFraction() {
if (this.char === CHAR_PERIOD) {
this.consume()
this.next(this.parseDateTimeFraction)
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
this.consume()
this.next(this.parseTimeZoneHour)
} else if (this.char === CHAR_Z) {
this.consume()
return this.return(createDateTime(this.state.result + this.state.buf))
} else if (this.atEndOfWord()) {
return this.returnNow(createDateTimeFloat(this.state.result + this.state.buf))
} else {
throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z'))
}
}
parseDateTimeFraction() {
if (isDigit(this.char)) {
this.consume()
} else if (this.state.buf.length === 1) {
throw this.error(new TomlError('Expected digit in milliseconds'))
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
this.consume()
this.next(this.parseTimeZoneHour)
} else if (this.char === CHAR_Z) {
this.consume()
return this.return(createDateTime(this.state.result + this.state.buf))
} else if (this.atEndOfWord()) {
return this.returnNow(createDateTimeFloat(this.state.result + this.state.buf))
} else {
throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z'))
}
}
parseTimeZoneHour() {
if (isDigit(this.char)) {
this.consume()
// FIXME: No more regexps
if (/\d\d$/.test(this.state.buf)) return this.next(this.parseTimeZoneSep)
} else {
throw this.error(new TomlError('Unexpected character in datetime, expected digit'))
}
}
parseTimeZoneSep() {
if (this.char === CHAR_COLON) {
this.consume()
this.next(this.parseTimeZoneMin)
} else {
throw this.error(new TomlError('Unexpected character in datetime, expected colon'))
}
}
parseTimeZoneMin() {
if (isDigit(this.char)) {
this.consume()
if (/\d\d$/.test(this.state.buf)) return this.return(createDateTime(this.state.result + this.state.buf))
} else {
throw this.error(new TomlError('Unexpected character in datetime, expected digit'))
}
}
/* BOOLEAN */
parseBoolean() {
/* istanbul ignore else */
if (this.char === CHAR_t) {
this.consume()
return this.next(this.parseTrue_r)
} else if (this.char === CHAR_f) {
this.consume()
return this.next(this.parseFalse_a)
}
}
parseTrue_r() {
if (this.char === CHAR_r) {
this.consume()
return this.next(this.parseTrue_u)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
parseTrue_u() {
if (this.char === CHAR_u) {
this.consume()
return this.next(this.parseTrue_e)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
parseTrue_e() {
if (this.char === CHAR_e) {
return this.return(true)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
parseFalse_a() {
if (this.char === CHAR_a) {
this.consume()
return this.next(this.parseFalse_l)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
parseFalse_l() {
if (this.char === CHAR_l) {
this.consume()
return this.next(this.parseFalse_s)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
parseFalse_s() {
if (this.char === CHAR_s) {
this.consume()
return this.next(this.parseFalse_e)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
parseFalse_e() {
if (this.char === CHAR_e) {
return this.return(false)
} else {
throw this.error(new TomlError('Invalid boolean, expected true or false'))
}
}
/* INLINE LISTS */
parseInlineList() {
if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) {
return null
} else if (this.char === Parser.END) {
throw this.error(new TomlError('Unterminated inline array'))
} else if (this.char === CHAR_NUM) {
return this.call(this.parseComment)
} else if (this.char === CHAR_RSQB) {
return this.return(this.state.resultArr || InlineList())
} else {
return this.callNow(this.parseValue, this.recordInlineListValue)
}
}
recordInlineListValue(value) {
if (!this.state.resultArr) {
this.state.resultArr = InlineList(tomlType(value))
}
if (isFloat(value) || isInteger(value)) {
// unbox now that we've verified they're ok
this.state.resultArr.push(value.valueOf())
} else {
this.state.resultArr.push(value)
}
return this.goto(this.parseInlineListNext)
}
parseInlineListNext() {
if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) {
return null
} else if (this.char === CHAR_NUM) {
return this.call(this.parseComment)
} else if (this.char === CHAR_COMMA) {
return this.next(this.parseInlineList)
} else if (this.char === CHAR_RSQB) {
return this.goto(this.parseInlineList)
} else {
throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])'))
}
}
/* INLINE TABLE */
parseInlineTable() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
throw this.error(new TomlError('Unterminated inline array'))
} else if (this.char === CHAR_RCUB) {
return this.return(this.state.resultTable || InlineTable())
} else {
if (!this.state.resultTable) this.state.resultTable = InlineTable()
return this.callNow(this.parseAssign, this.recordInlineTableValue)
}
}
recordInlineTableValue(kv) {
let target = this.state.resultTable
let finalKey = kv.key.pop()
for (let kw of kv.key) {
if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) {
throw this.error(new TomlError("Can't redefine existing key"))
}
target = target[kw] = target[kw] || Table()
}
if (hasKey(target, finalKey)) {
throw this.error(new TomlError("Can't redefine existing key"))
}
if (isInteger(kv.value) || isFloat(kv.value)) {
target[finalKey] = kv.value.valueOf()
} else {
target[finalKey] = kv.value
}
return this.goto(this.parseInlineTableNext)
}
parseInlineTableNext() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
throw this.error(new TomlError('Unterminated inline array'))
} else if (this.char === CHAR_COMMA) {
return this.next(this.parseInlineTablePostComma)
} else if (this.char === CHAR_RCUB) {
return this.goto(this.parseInlineTable)
} else {
throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])'))
}
}
parseInlineTablePostComma() {
if (this.char === CHAR_SP || this.char === CTRL_I) {
return null
} else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
throw this.error(new TomlError('Unterminated inline array'))
} else if (this.char === CHAR_COMMA) {
throw this.error(new TomlError('Empty elements in inline tables are not permitted'))
} else if (this.char === CHAR_RCUB) {
throw this.error(new TomlError('Trailing commas in inline tables are not permitted'))
} else {
return this.goto(this.parseInlineTable)
}
}
}
return TOMLParser
}
function prettyError(err, buf) {
/* istanbul ignore if */
if (err.pos == null || err.line == null) return err
let msg = err.message
msg += ` at row ${err.line + 1}, col ${err.col + 1}, pos ${err.pos}:\n`
/* istanbul ignore else */
if (buf && buf.split) {
const lines = buf.split(/\n/)
const lineNumWidth = String(Math.min(lines.length, err.line + 3)).length
let linePadding = ' '
while (linePadding.length < lineNumWidth) linePadding += ' '
for (let ii = Math.max(0, err.line - 1); ii < Math.min(lines.length, err.line + 2); ++ii) {
let lineNum = String(ii + 1)
if (lineNum.length < lineNumWidth) lineNum = ' ' + lineNum
if (err.line === ii) {
msg += lineNum + '> ' + lines[ii] + '\n'
msg += linePadding + ' '
for (let hh = 0; hh < err.col; ++hh) {
msg += ' '
}
msg += '^\n'
} else {
msg += lineNum + ': ' + lines[ii] + '\n'
}
}
}
err.message = msg + '\n'
return err
}
const TOMLParser = makeParserClass(Parser);
function parseString(str) {
str = str.toString('utf8')
const parser = new TOMLParser()
try {
parser.parse(str)
return parser.finish()
} catch (err) {
throw prettyError(err, str)
}
}
module.exports = parseString
});
ace.define('ace/mode/toml_worker', [], function (require, exports, module) {
"use strict";
var oop = require("../lib/oop");
var Mirror = require("../worker/mirror").Mirror;
const parse = require("./toml/toml_parse");
var TomlWorker = exports.TomlWorker = function (sender) {
Mirror.call(this, sender);
this.setTimeout(200);
};
oop.inherits(TomlWorker, Mirror);
(function () {
this.onUpdate = function () {
var value = this.doc.getValue();
var errors = [];
try {
if (value) {
parse(value);
}
} catch (e) {
var pos = this.doc.indexToPosition(e.pos - 1);
errors.push({
row: pos.row,
column: pos.column,
text: e.message,
type: "error"
});
}
this.sender.emit("annotate", errors);
};
}).call(TomlWorker.prototype);
exports.TomlWorker = TomlWorker;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment