Click three times on a textarea you want to replace - Ace will replace it.
+
To change settings, use Ctrl-, shortcut. (Cmd-, on mac).
+
+
+
+
+
+
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/bookmarklet/style.css b/pvt-www/_builtin/js/ace-1.4.8/demo/bookmarklet/style.css
new file mode 100644
index 0000000..3fce509
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/bookmarklet/style.css
@@ -0,0 +1,226 @@
+body {
+ margin:0;
+ padding:0;
+ background-color:#e6f5fc;
+
+}
+
+H2, H3, H4 {
+ font-family:Trebuchet MS;
+ font-weight:bold;
+ margin:0;
+ padding:0;
+}
+
+H2 {
+ font-size:28px;
+ color:#263842;
+ padding-bottom:6px;
+}
+
+H3 {
+ font-family:Trebuchet MS;
+ font-weight:bold;
+ font-size:22px;
+ color:#253741;
+ margin-top:43px;
+ margin-bottom:8px;
+}
+
+H4 {
+ font-family:Trebuchet MS;
+ font-weight:bold;
+ font-size:21px;
+ color:#222222;
+ margin-bottom:4px;
+}
+
+P {
+ padding:13px 0;
+ margin:0;
+ line-height:22px;
+}
+
+UL{
+ line-height : 22px;
+}
+
+PRE{
+ background : #333;
+ color : white;
+ padding : 10px;
+}
+
+#header {
+ height : 227px;
+ position:relative;
+ overflow:hidden;
+ background: url(images/background.png) repeat-x 0 0;
+ border-bottom:1px solid #c9e8fa;
+}
+
+#header .content .signature {
+ font-family:Trebuchet MS;
+ font-size:11px;
+ color:#ebe4d6;
+ position:absolute;
+ bottom:5px;
+ right:42px;
+ letter-spacing : 1px;
+}
+
+.content {
+ width:970px;
+ position:relative;
+ margin:0 auto;
+}
+
+#header .content {
+ height:184px;
+ margin-top:22px;
+}
+
+#header .content .logo {
+ width : 282px;
+ height : 184px;
+ background:url(images/logo.png) no-repeat 0 0;
+ position:absolute;
+ top:0;
+ left:0;
+}
+
+#header .content .title {
+ width : 605px;
+ height : 58px;
+ background:url(images/ace.png) no-repeat 0 0;
+ position:absolute;
+ top:98px;
+ left:329px;
+}
+
+#wrapper {
+ background:url(images/body_background.png) repeat-x 0 0;
+ min-height:250px;
+}
+
+#wrapper .content {
+ font-family:Arial;
+ font-size:14px;
+ color:#222222;
+ width:1000px;
+}
+
+#wrapper .content .column1 {
+ position:relative;
+ float:left;
+ width:315px;
+ margin-right:31px;
+}
+
+#wrapper .content .column2 {
+ position:relative;
+ float:left;
+ width:600px;
+ padding-top:47px;
+}
+
+.fork_on_github {
+ width:310px;
+ height:80px;
+ background:url(images/fork_on_github.png) no-repeat 0 0;
+ position:relative;
+ overflow:hidden;
+ cursor:pointer;
+}
+
+.fork_on_github:hover {
+ background-position:0 -80px;
+}
+
+.divider {
+ height:3px;
+ background-color:#bedaea;
+ margin-bottom:3px;
+}
+
+.menu {
+ padding:23px 0 0 24px;
+}
+
+UL.content-list {
+ padding:15px;
+ margin:0;
+}
+
+UL.menu-list {
+ padding:0;
+ margin:0 0 20px 0;
+ list-style-type:none;
+ line-height : 16px;
+}
+
+UL.menu-list LI {
+ color:#2557b4;
+ font-family:Trebuchet MS;
+ font-size:14px;
+ padding:7px 0;
+ border-bottom:1px dotted #d6e2e7;
+}
+
+UL.menu-list LI:last-child {
+ border-bottom:0;
+}
+
+A {
+ color:#2557b4;
+ text-decoration:none;
+}
+
+A:hover {
+ text-decoration:underline;
+}
+
+P#first{
+ background : rgba(255,255,255,0.5);
+ padding : 20px;
+ font-size : 16px;
+ line-height : 24px;
+ margin : 0 0 20px 0;
+}
+
+#footer {
+ height:40px;
+ position:relative;
+ overflow:hidden;
+ background:url(images/bottombar.png) repeat-x 0 0;
+ position:relative;
+ margin-top:40px;
+}
+
+UL.menu-footer {
+ padding:0;
+ margin:8px 11px 0 0;
+ list-style-type:none;
+ float:right;
+}
+
+UL.menu-footer LI {
+ color:white;
+ font-family:Arial;
+ font-size:12px;
+ display:inline-block;
+ margin:0 1px;
+}
+
+UL.menu-footer LI A {
+ color:#8dd0ff;
+ text-decoration:none;
+}
+
+UL.menu-footer LI A:hover {
+ text-decoration:underline;
+}
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/chromevox.html b/pvt-www/_builtin/js/ace-1.4.8/demo/chromevox.html
new file mode 100644
index 0000000..a2d7cfa
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/chromevox.html
@@ -0,0 +1,39 @@
+
+
+
+
+ ACE ChromeVox demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/code_lens.html b/pvt-www/_builtin/js/ace-1.4.8/demo/code_lens.html
new file mode 100644
index 0000000..238141f
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/code_lens.html
@@ -0,0 +1,122 @@
+
+
+
+
+ ACE Code Lens demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/emmet.html b/pvt-www/_builtin/js/ace-1.4.8/demo/emmet.html
new file mode 100644
index 0000000..0d57f32
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/emmet.html
@@ -0,0 +1,41 @@
+
+
+
+
+ ACE Emmet demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/iframe.html b/pvt-www/_builtin/js/ace-1.4.8/demo/iframe.html
new file mode 100644
index 0000000..c4bf6c3
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/iframe.html
@@ -0,0 +1,30 @@
+
+
+
+
+ ACE Editor Inside iframe
+
+
+
+
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/keyboard_shortcuts.html b/pvt-www/_builtin/js/ace-1.4.8/demo/keyboard_shortcuts.html
new file mode 100644
index 0000000..dd4e42b
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/keyboard_shortcuts.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+ Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/ace-logo.png b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/ace-logo.png
new file mode 100644
index 0000000..886a8df
Binary files /dev/null and b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/ace-logo.png differ
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/demo.js b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/demo.js
new file mode 100644
index 0000000..a75abea
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/demo.js
@@ -0,0 +1,7678 @@
+define("ace/ext/rtl",["require","exports","module","ace/editor","ace/config"], function(require, exports, module) {
+"use strict";
+
+var commands = [{
+ name: "leftToRight",
+ bindKey: { win: "Ctrl-Alt-Shift-L", mac: "Command-Alt-Shift-L" },
+ exec: function(editor) {
+ editor.session.$bidiHandler.setRtlDirection(editor, false);
+ },
+ readOnly: true
+}, {
+ name: "rightToLeft",
+ bindKey: { win: "Ctrl-Alt-Shift-R", mac: "Command-Alt-Shift-R" },
+ exec: function(editor) {
+ editor.session.$bidiHandler.setRtlDirection(editor, true);
+ },
+ readOnly: true
+}];
+
+var Editor = require("../editor").Editor;
+require("../config").defineOptions(Editor.prototype, "editor", {
+ rtlText: {
+ set: function(val) {
+ if (val) {
+ this.on("change", onChange);
+ this.on("changeSelection", onChangeSelection);
+ this.renderer.on("afterRender", updateLineDirection);
+ this.commands.on("exec", onCommandEmitted);
+ this.commands.addCommands(commands);
+ } else {
+ this.off("change", onChange);
+ this.off("changeSelection", onChangeSelection);
+ this.renderer.off("afterRender", updateLineDirection);
+ this.commands.off("exec", onCommandEmitted);
+ this.commands.removeCommands(commands);
+ clearTextLayer(this.renderer);
+ }
+ this.renderer.updateFull();
+ }
+ },
+ rtl: {
+ set: function(val) {
+ this.session.$bidiHandler.$isRtl = val;
+ if (val) {
+ this.setOption("rtlText", false);
+ this.renderer.on("afterRender", updateLineDirection);
+ this.session.$bidiHandler.seenBidi = true;
+ } else {
+ this.renderer.off("afterRender", updateLineDirection);
+ clearTextLayer(this.renderer);
+ }
+ this.renderer.updateFull();
+ }
+ }
+});
+function onChangeSelection(e, editor) {
+ var lead = editor.getSelection().lead;
+ if (editor.session.$bidiHandler.isRtlLine(lead.row)) {
+ if (lead.column === 0) {
+ if (editor.session.$bidiHandler.isMoveLeftOperation && lead.row > 0) {
+ editor.getSelection().moveCursorTo(lead.row - 1, editor.session.getLine(lead.row - 1).length);
+ } else {
+ if (editor.getSelection().isEmpty())
+ lead.column += 1;
+ else
+ lead.setPosition(lead.row, lead.column + 1);
+ }
+ }
+ }
+}
+
+function onCommandEmitted(commadEvent) {
+ commadEvent.editor.session.$bidiHandler.isMoveLeftOperation = /gotoleft|selectleft|backspace|removewordleft/.test(commadEvent.command.name);
+}
+function onChange(delta, editor) {
+ var session = editor.session;
+ session.$bidiHandler.currentRow = null;
+ if (session.$bidiHandler.isRtlLine(delta.start.row) && delta.action === 'insert' && delta.lines.length > 1) {
+ for (var row = delta.start.row; row < delta.end.row; row++) {
+ if (session.getLine(row + 1).charAt(0) !== session.$bidiHandler.RLE)
+ session.doc.$lines[row + 1] = session.$bidiHandler.RLE + session.getLine(row + 1);
+ }
+ }
+}
+
+function updateLineDirection(e, renderer) {
+ var session = renderer.session;
+ var $bidiHandler = session.$bidiHandler;
+ var cells = renderer.$textLayer.$lines.cells;
+ var width = renderer.layerConfig.width - renderer.layerConfig.padding + "px";
+ cells.forEach(function(cell) {
+ var style = cell.element.style;
+ if ($bidiHandler && $bidiHandler.isRtlLine(cell.row)) {
+ style.direction = "rtl";
+ style.textAlign = "right";
+ style.width = width;
+ } else {
+ style.direction = "";
+ style.textAlign = "";
+ style.width = "";
+ }
+ });
+}
+
+function clearTextLayer(renderer) {
+ var lines = renderer.$textLayer.$lines;
+ lines.cells.forEach(clear);
+ lines.cellCache.forEach(clear);
+ function clear(cell) {
+ var style = cell.element.style;
+ style.direction = style.textAlign = style.width = "";
+ }
+}
+
+});
+
+define("kitchen-sink/inline_editor",["require","exports","module","ace/line_widgets","ace/editor","ace/virtual_renderer","ace/lib/dom","ace/commands/default_commands"], function(require, exports, module) {
+"use strict";
+
+var LineWidgets = require("ace/line_widgets").LineWidgets;
+var Editor = require("ace/editor").Editor;
+var Renderer = require("ace/virtual_renderer").VirtualRenderer;
+var dom = require("ace/lib/dom");
+
+
+require("ace/commands/default_commands").commands.push({
+ name: "openInlineEditor",
+ bindKey: "F3",
+ exec: function(editor) {
+ var split = window.env.split;
+ var s = editor.session;
+ var inlineEditor = new Editor(new Renderer());
+ var splitSession = split.$cloneSession(s);
+
+ var row = editor.getCursorPosition().row;
+ if (editor.session.lineWidgets && editor.session.lineWidgets[row]) {
+ editor.session.lineWidgets[row].destroy();
+ return;
+ }
+
+ var rowCount = 10;
+ var w = {
+ row: row,
+ fixedWidth: true,
+ el: dom.createElement("div"),
+ editor: inlineEditor
+ };
+ var el = w.el;
+ el.appendChild(inlineEditor.container);
+
+ if (!editor.session.widgetManager) {
+ editor.session.widgetManager = new LineWidgets(editor.session);
+ editor.session.widgetManager.attach(editor);
+ }
+
+ var h = rowCount*editor.renderer.layerConfig.lineHeight;
+ inlineEditor.container.style.height = h + "px";
+
+ el.style.position = "absolute";
+ el.style.zIndex = "4";
+ el.style.borderTop = "solid blue 2px";
+ el.style.borderBottom = "solid blue 2px";
+
+ inlineEditor.setSession(splitSession);
+ editor.session.widgetManager.addLineWidget(w);
+
+ var kb = {
+ handleKeyboard:function(_,hashId, keyString) {
+ if (hashId === 0 && keyString === "esc") {
+ w.destroy();
+ return true;
+ }
+ }
+ };
+
+ w.destroy = function() {
+ editor.keyBinding.removeKeyboardHandler(kb);
+ s.widgetManager.removeLineWidget(w);
+ };
+
+ editor.keyBinding.addKeyboardHandler(kb);
+ inlineEditor.keyBinding.addKeyboardHandler(kb);
+ inlineEditor.setTheme("ace/theme/solarized_light");
+ }
+});
+});
+
+define("ace/test/asyncjs/assert",["require","exports","module","ace/lib/oop"], function(require, exports, module) {
+var oop = require("ace/lib/oop");
+var pSlice = Array.prototype.slice;
+
+var assert = exports;
+
+assert.AssertionError = function AssertionError(options) {
+ this.name = 'AssertionError';
+ this.message = options.message;
+ this.actual = options.actual;
+ this.expected = options.expected;
+ this.operator = options.operator;
+ var stackStartFunction = options.stackStartFunction || fail;
+
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, stackStartFunction);
+ }
+};
+oop.inherits(assert.AssertionError, Error);
+
+toJSON = function(obj) {
+ if (typeof JSON !== "undefined")
+ return JSON.stringify(obj);
+ else
+ return obj.toString();
+}
+
+assert.AssertionError.prototype.toString = function() {
+ if (this.message) {
+ return [this.name + ':', this.message].join(' ');
+ } else {
+ return [this.name + ':',
+ toJSON(this.expected),
+ this.operator,
+ toJSON(this.actual)].join(' ');
+ }
+};
+
+assert.AssertionError.__proto__ = Error.prototype;
+
+function fail(actual, expected, message, operator, stackStartFunction) {
+ throw new assert.AssertionError({
+ message: message,
+ actual: actual,
+ expected: expected,
+ operator: operator,
+ stackStartFunction: stackStartFunction
+ });
+}
+assert.fail = fail;
+
+assert.ok = function ok(value, message) {
+ if (!!!value) fail(value, true, message, '==', assert.ok);
+};
+
+assert.equal = function equal(actual, expected, message) {
+ if (actual != expected) fail(actual, expected, message, '==', assert.equal);
+};
+
+assert.notEqual = function notEqual(actual, expected, message) {
+ if (actual == expected) {
+ fail(actual, expected, message, '!=', assert.notEqual);
+ }
+};
+
+assert.deepEqual = function deepEqual(actual, expected, message) {
+ if (!_deepEqual(actual, expected)) {
+ fail(actual, expected, message, 'deepEqual', assert.deepEqual);
+ }
+};
+
+function _deepEqual(actual, expected) {
+ if (actual === expected) {
+ return true;
+
+ } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
+ if (actual.length != expected.length) return false;
+
+ for (var i = 0; i < actual.length; i++) {
+ if (actual[i] !== expected[i]) return false;
+ }
+
+ return true;
+ } else if (actual instanceof Date && expected instanceof Date) {
+ return actual.getTime() === expected.getTime();
+ } else if (typeof actual != 'object' && typeof expected != 'object') {
+ return actual == expected;
+ } else {
+ return objEquiv(actual, expected);
+ }
+}
+
+function isUndefinedOrNull(value) {
+ return value === null || value === undefined;
+}
+
+function isArguments(object) {
+ return Object.prototype.toString.call(object) == '[object Arguments]';
+}
+
+function objEquiv(a, b) {
+ if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
+ return false;
+ if (a.prototype !== b.prototype) return false;
+ if (isArguments(a)) {
+ if (!isArguments(b)) {
+ return false;
+ }
+ a = pSlice.call(a);
+ b = pSlice.call(b);
+ return _deepEqual(a, b);
+ }
+ try {
+ var ka = Object.keys(a),
+ kb = Object.keys(b),
+ key, i;
+ } catch (e) {//happens when one is a string literal and the other isn't
+ return false;
+ }
+ if (ka.length != kb.length)
+ return false;
+ ka.sort();
+ kb.sort();
+ for (i = ka.length - 1; i >= 0; i--) {
+ if (ka[i] != kb[i])
+ return false;
+ }
+ for (i = ka.length - 1; i >= 0; i--) {
+ key = ka[i];
+ if (!_deepEqual(a[key], b[key])) return false;
+ }
+ return true;
+}
+
+assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
+ if (_deepEqual(actual, expected)) {
+ fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
+ }
+};
+
+assert.strictEqual = function strictEqual(actual, expected, message) {
+ if (actual !== expected) {
+ fail(actual, expected, message, '===', assert.strictEqual);
+ }
+};
+
+assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
+ if (actual === expected) {
+ fail(actual, expected, message, '!==', assert.notStrictEqual);
+ }
+};
+
+function expectedException(actual, expected) {
+ if (!actual || !expected) {
+ return false;
+ }
+
+ if (expected instanceof RegExp) {
+ return expected.test(actual);
+ } else if (actual instanceof expected) {
+ return true;
+ } else if (expected.call({}, actual) === true) {
+ return true;
+ }
+
+ return false;
+}
+
+function _throws(shouldThrow, block, expected, message) {
+ var actual;
+
+ if (typeof expected === 'string') {
+ message = expected;
+ expected = null;
+ }
+
+ try {
+ block();
+ } catch (e) {
+ actual = e;
+ }
+
+ message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
+ (message ? ' ' + message : '.');
+
+ if (shouldThrow && !actual) {
+ fail('Missing expected exception' + message);
+ }
+
+ if (!shouldThrow && expectedException(actual, expected)) {
+ fail('Got unwanted exception' + message);
+ }
+
+ if ((shouldThrow && actual && expected &&
+ !expectedException(actual, expected)) || (!shouldThrow && actual)) {
+ throw actual;
+ }
+}
+
+assert.throws = function(block, /*optional*/error, /*optional*/message) {
+ _throws.apply(this, [true].concat(pSlice.call(arguments)));
+};
+assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
+ _throws.apply(this, [false].concat(pSlice.call(arguments)));
+};
+
+assert.ifError = function(err) { if (err) {throw err;}};
+
+});
+
+define("ace/test/asyncjs/async",["require","exports","module"], function(require, exports, module) {
+
+var STOP = exports.STOP = {}
+
+exports.Generator = function(source) {
+ if (typeof source == "function")
+ this.source = {
+ next: source
+ }
+ else
+ this.source = source
+}
+
+;(function() {
+ this.next = function(callback) {
+ this.source.next(callback)
+ }
+
+ this.map = function(mapper) {
+ if (!mapper)
+ return this
+
+ mapper = makeAsync(1, mapper)
+
+ var source = this.source
+ this.next = function(callback) {
+ source.next(function(err, value) {
+ if (err)
+ callback(err)
+ else {
+ mapper(value, function(err, value) {
+ if (err)
+ callback(err)
+ else
+ callback(null, value)
+ })
+ }
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.filter = function(filter) {
+ if (!filter)
+ return this
+
+ filter = makeAsync(1, filter)
+
+ var source = this.source
+ this.next = function(callback) {
+ source.next(function handler(err, value) {
+ if (err)
+ callback(err)
+ else {
+ filter(value, function(err, takeIt) {
+ if (err)
+ callback(err)
+ else if (takeIt)
+ callback(null, value)
+ else
+ source.next(handler)
+ })
+ }
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.slice = function(begin, end) {
+ var count = -1
+ if (!end || end < 0)
+ var end = Infinity
+
+ var source = this.source
+ this.next = function(callback) {
+ source.next(function handler(err, value) {
+ count++
+ if (err)
+ callback(err)
+ else if (count >= begin && count < end)
+ callback(null, value)
+ else if (count >= end)
+ callback(STOP)
+ else
+ source.next(handler)
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.reduce = function(reduce, initialValue) {
+ reduce = makeAsync(3, reduce)
+
+ var index = 0
+ var done = false
+ var previousValue = initialValue
+
+ var source = this.source
+ this.next = function(callback) {
+ if (done)
+ return callback(STOP)
+
+ if (initialValue === undefined) {
+ source.next(function(err, currentValue) {
+ if (err)
+ return callback(err, previousValue)
+
+ previousValue = currentValue
+ reduceAll()
+ })
+ }
+ else
+ reduceAll()
+
+ function reduceAll() {
+ source.next(function handler(err, currentValue) {
+ if (err) {
+ done = true
+ if (err == STOP)
+ return callback(null, previousValue)
+ else
+ return(err)
+ }
+ reduce(previousValue, currentValue, index++, function(err, value) {
+ previousValue = value
+ source.next(handler)
+ })
+ })
+ }
+ }
+ return new this.constructor(this)
+ }
+
+ this.forEach =
+ this.each = function(fn) {
+ fn = makeAsync(1, fn)
+
+ var source = this.source
+ this.next = function(callback) {
+ source.next(function handler(err, value) {
+ if (err)
+ callback(err)
+ else {
+ fn(value, function(err) {
+ callback(err, value)
+ })
+ }
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.some = function(condition) {
+ condition = makeAsync(1, condition)
+
+ var source = this.source
+ var done = false
+ this.next = function(callback) {
+ if (done)
+ return callback(STOP)
+
+ source.next(function handler(err, value) {
+ if (err)
+ return callback(err)
+
+ condition(value, function(err, result) {
+ if (err) {
+ done = true
+ if (err == STOP)
+ callback(null, false)
+ else
+ callback(err)
+ }
+ else if (result) {
+ done = true
+ callback(null, true)
+ }
+ else
+ source.next(handler)
+ })
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.every = function(condition) {
+ condition = makeAsync(1, condition)
+
+ var source = this.source
+ var done = false
+ this.next = function(callback) {
+ if (done)
+ return callback(STOP)
+
+ source.next(function handler(err, value) {
+ if (err)
+ return callback(err)
+
+ condition(value, function(err, result) {
+ if (err) {
+ done = true
+ if (err == STOP)
+ callback(null, true)
+ else
+ callback(err)
+ }
+ else if (!result) {
+ done = true
+ callback(null, false)
+ }
+ else
+ source.next(handler)
+ })
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.call = function(context) {
+ var source = this.source
+ return this.map(function(fn, next) {
+ fn = makeAsync(0, fn, context)
+ fn.call(context, function(err, value) {
+ next(err, value)
+ })
+ })
+ }
+
+ this.concat = function(generator) {
+ var generators = [this]
+ generators.push.apply(generators, arguments)
+ var index = 0
+ var source = generators[index++]
+
+ return new this.constructor(function(callback) {
+ source.next(function handler(err, value) {
+ if (err) {
+ if (err == STOP) {
+ source = generators[index++]
+ if (!source)
+ return callback(STOP)
+ else
+ return source.next(handler)
+ }
+ else
+ return callback(err)
+ }
+ else
+ return callback(null, value)
+ })
+ })
+ }
+
+ this.zip = function(generator) {
+ var generators = [this]
+ generators.push.apply(generators, arguments)
+
+ return new this.constructor(function(callback) {
+ exports.list(generators)
+ .map(function(gen, next) {
+ gen.next(next)
+ })
+ .toArray(callback)
+ })
+ }
+
+ this.expand = function(inserter, constructor) {
+ if (!inserter)
+ return this
+
+ var inserter = makeAsync(1, inserter)
+ var constructor = constructor || this.constructor
+ var source = this.source;
+ var spliced = null;
+
+ return new constructor(function next(callback) {
+ if (!spliced) {
+ source.next(function(err, value) {
+ if (err)
+ return callback(err)
+
+ inserter(value, function(err, toInsert) {
+ if (err)
+ return callback(err)
+
+ spliced = toInsert
+ next(callback)
+ })
+
+ })
+ }
+ else {
+ spliced.next(function(err, value) {
+ if (err == STOP) {
+ spliced = null
+ return next(callback)
+ }
+ else if (err)
+ return callback(err)
+
+ callback(err, value)
+ })
+ }
+ })
+ }
+
+ this.sort = function(compare) {
+ var self = this
+ var arrGen
+ this.next = function(callback) {
+ if (arrGen)
+ return arrGen.next(callback)
+
+ self.toArray(function(err, arr) {
+ if (err)
+ callback(err)
+ else {
+ arrGen = exports.list(arr.sort(compare))
+ arrGen.next(callback)
+ }
+ })
+ }
+ return new this.constructor(this)
+ }
+
+ this.join = function(separator) {
+ return this.$arrayOp(Array.prototype.join, separator !== undefined ? [separator] : null)
+ }
+
+ this.reverse = function() {
+ return this.$arrayOp(Array.prototype.reverse)
+ }
+
+ this.$arrayOp = function(arrayMethod, args) {
+ var self = this
+ var i = 0
+ this.next = function(callback) {
+ if (i++ > 0)
+ return callback(STOP)
+
+ self.toArray(function(err, arr) {
+ if (err)
+ callback(err, "")
+ else {
+ if (args)
+ callback(null, arrayMethod.apply(arr, args))
+ else
+ callback(null, arrayMethod.call(arr))
+ }
+ })
+ }
+ return new this.constructor(this)
+
+ }
+
+ this.end = function(breakOnError, callback) {
+ if (!callback) {
+ callback = arguments[0]
+ breakOnError = true
+ }
+
+ var source = this.source
+ var last
+ var lastError
+ source.next(function handler(err, value) {
+ if (err) {
+ if (err == STOP)
+ callback && callback(lastError, last)
+ else if (!breakOnError) {
+ lastError = err
+ source.next(handler)
+ }
+ else
+ callback && callback(err, value)
+ }
+ else {
+ last = value
+ source.next(handler)
+ }
+ })
+ }
+
+ this.toArray = function(breakOnError, callback) {
+ if (!callback) {
+ callback = arguments[0]
+ breakOnError = true
+ }
+
+ var values = []
+ var errors = []
+ var source = this.source
+
+ source.next(function handler(err, value) {
+ if (err) {
+ if (err == STOP) {
+ if (breakOnError)
+ return callback(null, values)
+ else {
+ errors.length = values.length
+ return callback(errors, values)
+ }
+ }
+ else {
+ if (breakOnError)
+ return callback(err)
+ else
+ errors[values.length] = err
+ }
+ }
+
+ values.push(value)
+ source.next(handler)
+ })
+ }
+
+}).call(exports.Generator.prototype)
+
+var makeAsync = exports.makeAsync = function(args, fn, context) {
+ if (fn.length > args)
+ return fn
+ else {
+ return function() {
+ var value
+ var next = arguments[args]
+ try {
+ value = fn.apply(context || this, arguments)
+ } catch(e) {
+ return next(e)
+ }
+ next(null, value)
+ }
+ }
+}
+
+exports.list = function(arr, construct) {
+ var construct = construct || exports.Generator
+ var i = 0
+ var len = arr.length
+
+ return new construct(function(callback) {
+ if (i < len)
+ callback(null, arr[i++])
+ else
+ callback(STOP)
+ })
+}
+
+exports.values = function(map, construct) {
+ var values = []
+ for (var key in map)
+ values.push(map[key])
+
+ return exports.list(values, construct)
+}
+
+exports.keys = function(map, construct) {
+ var keys = []
+ for (var key in map)
+ keys.push(key)
+
+ return exports.list(keys, construct)
+}
+exports.range = function(start, stop, step, construct) {
+ var construct = construct || exports.Generator
+ start = start || 0
+ step = step || 1
+
+ if (stop === undefined || stop === null)
+ stop = step > 0 ? Infinity : -Infinity
+
+ var value = start
+
+ return new construct(function(callback) {
+ if (step > 0 && value >= stop || step < 0 && value <= stop)
+ callback(STOP)
+ else {
+ var current = value
+ value += step
+ callback(null, current)
+ }
+ })
+}
+
+exports.concat = function(first, varargs) {
+ if (arguments.length > 1)
+ return first.concat.apply(first, Array.prototype.slice.call(arguments, 1))
+ else
+ return first
+}
+
+exports.zip = function(first, varargs) {
+ if (arguments.length > 1)
+ return first.zip.apply(first, Array.prototype.slice.call(arguments, 1))
+ else
+ return first.map(function(item, next) {
+ next(null, [item])
+ })
+}
+
+
+exports.plugin = function(members, constructors) {
+ if (members) {
+ for (var key in members) {
+ exports.Generator.prototype[key] = members[key]
+ }
+ }
+
+ if (constructors) {
+ for (var key in constructors) {
+ exports[key] = constructors[key]
+ }
+ }
+}
+
+})
+
+define("ace/test/mockrenderer",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+var MockRenderer = exports.MockRenderer = function(visibleRowCount) {
+ if (typeof document == "object") {
+ this.container = document.createElement("div");
+ this.scroller = document.createElement("div");
+ this.$gutter = document.createElement("div");
+ }
+ this.visibleRowCount = visibleRowCount || 20;
+
+ this.layerConfig = {
+ firstVisibleRow : 0,
+ lastVisibleRow : this.visibleRowCount
+ };
+
+ this.isMockRenderer = true;
+};
+
+
+MockRenderer.prototype.getFirstVisibleRow = function() {
+ return this.layerConfig.firstVisibleRow;
+};
+
+MockRenderer.prototype.getLastVisibleRow = function() {
+ return this.layerConfig.lastVisibleRow;
+};
+
+MockRenderer.prototype.getFirstFullyVisibleRow = function() {
+ return this.layerConfig.firstVisibleRow;
+};
+
+MockRenderer.prototype.getLastFullyVisibleRow = function() {
+ return this.layerConfig.lastVisibleRow;
+};
+
+MockRenderer.prototype.getContainerElement = function() {
+ return this.container;
+};
+
+MockRenderer.prototype.getMouseEventTarget = function() {
+ return this.container;
+};
+
+MockRenderer.prototype.getTextAreaContainer = function() {
+ return this.container;
+};
+
+MockRenderer.prototype.addGutterDecoration = function() {
+};
+
+MockRenderer.prototype.removeGutterDecoration = function() {
+};
+
+MockRenderer.prototype.moveTextAreaToCursor = function() {
+};
+
+MockRenderer.prototype.setSession = function(session) {
+ this.session = session;
+};
+
+MockRenderer.prototype.getSession = function(session) {
+ return this.session;
+};
+
+MockRenderer.prototype.setTokenizer = function() {
+};
+
+MockRenderer.prototype.on = function() {
+};
+
+MockRenderer.prototype.updateCursor = function() {
+};
+
+MockRenderer.prototype.animateScrolling = function(fromValue, callback) {
+ callback && callback();
+};
+
+MockRenderer.prototype.scrollToX = function(scrollTop) {};
+MockRenderer.prototype.scrollToY = function(scrollLeft) {};
+
+MockRenderer.prototype.scrollToLine = function(line, center) {
+ var lineHeight = 16;
+ var row = 0;
+ for (var l = 1; l < line; l++) {
+ row += this.session.getRowLength(l-1);
+ }
+
+ if (center) {
+ row -= this.visibleRowCount / 2;
+ }
+ this.scrollToRow(row);
+};
+
+MockRenderer.prototype.scrollSelectionIntoView = function() {
+};
+
+MockRenderer.prototype.scrollCursorIntoView = function() {
+ var cursor = this.session.getSelection().getCursor();
+ if (cursor.row < this.layerConfig.firstVisibleRow) {
+ this.scrollToRow(cursor.row);
+ }
+ else if (cursor.row > this.layerConfig.lastVisibleRow) {
+ this.scrollToRow(cursor.row);
+ }
+};
+
+MockRenderer.prototype.scrollToRow = function(row) {
+ var row = Math.min(this.session.getLength() - this.visibleRowCount, Math.max(0,
+ row));
+ this.layerConfig.firstVisibleRow = row;
+ this.layerConfig.lastVisibleRow = row + this.visibleRowCount;
+};
+
+MockRenderer.prototype.getScrollTopRow = function() {
+ return this.layerConfig.firstVisibleRow;
+};
+
+MockRenderer.prototype.draw = function() {
+};
+
+MockRenderer.prototype.onChangeTabSize = function(startRow, endRow) {
+};
+
+MockRenderer.prototype.updateLines = function(startRow, endRow) {
+};
+
+MockRenderer.prototype.updateBackMarkers = function() {
+};
+
+MockRenderer.prototype.updateFrontMarkers = function() {
+};
+
+MockRenderer.prototype.updateBreakpoints = function() {
+};
+
+MockRenderer.prototype.onResize = function() {
+};
+
+MockRenderer.prototype.updateFull = function() {
+};
+
+MockRenderer.prototype.updateText = function() {
+};
+
+MockRenderer.prototype.showCursor = function() {
+};
+
+MockRenderer.prototype.visualizeFocus = function() {
+};
+
+MockRenderer.prototype.setAnnotations = function() {
+};
+
+MockRenderer.prototype.setStyle = function() {
+};
+
+MockRenderer.prototype.unsetStyle = function() {
+};
+
+MockRenderer.prototype.textToScreenCoordinates = function() {
+ return {
+ pageX: 0,
+ pageY: 0
+ };
+};
+
+MockRenderer.prototype.screenToTextCoordinates = function() {
+ return {
+ row: 0,
+ column: 0
+ };
+};
+
+MockRenderer.prototype.adjustWrapLimit = function () {
+
+};
+
+});
+
+define("kitchen-sink/dev_util",["require","exports","module","ace/lib/dom","ace/lib/event","ace/range","ace/edit_session","ace/undomanager","ace/lib/oop","ace/lib/dom","ace/range","ace/editor","ace/test/asyncjs/assert","ace/test/asyncjs/async","ace/undomanager","ace/edit_session","ace/test/mockrenderer","ace/lib/event_emitter"], function(require, exports, module) {
+var dom = require("ace/lib/dom");
+var event = require("ace/lib/event");
+var Range = require("ace/range").Range;
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+function def(o, key, get) {
+ try {
+ Object.defineProperty(o, key, {
+ configurable: true,
+ get: get,
+ set: function(val) {
+ delete o[key];
+ o[key] = val;
+ }
+ });
+ } catch(e) {
+ console.error(e);
+ }
+}
+def(window, "ace", function(){ return window.env.editor });
+def(window, "editor", function(){ return window.env.editor == logEditor ? editor : window.env.editor });
+def(window, "session", function(){ return window.editor.session });
+def(window, "split", function(){ return window.env.split });
+
+
+def(window, "devUtil", function(){ return exports });
+
+exports.addGlobals = function() {
+ window.oop = require("ace/lib/oop");
+ window.dom = require("ace/lib/dom");
+ window.Range = require("ace/range").Range;
+ window.Editor = require("ace/editor").Editor;
+ window.assert = require("ace/test/asyncjs/assert");
+ window.asyncjs = require("ace/test/asyncjs/async");
+ window.UndoManager = require("ace/undomanager").UndoManager;
+ window.EditSession = require("ace/edit_session").EditSession;
+ window.MockRenderer = require("ace/test/mockrenderer").MockRenderer;
+ window.EventEmitter = require("ace/lib/event_emitter").EventEmitter;
+
+ window.getSelection = getSelection;
+ window.setSelection = setSelection;
+ window.testSelection = testSelection;
+ window.setValue = setValue;
+ window.testValue = testValue;
+ window.logToAce = exports.log;
+};
+
+function getSelection(editor) {
+ var data = editor.multiSelect.toJSON();
+ if (!data.length) data = [data];
+ data = data.map(function(x) {
+ var a, c;
+ if (x.isBackwards) {
+ a = x.end;
+ c = x.start;
+ } else {
+ c = x.end;
+ a = x.start;
+ }
+ return Range.comparePoints(a, c)
+ ? [a.row, a.column, c.row, c.column]
+ : [a.row, a.column];
+ });
+ return data.length > 1 ? data : data[0];
+}
+function setSelection(editor, data) {
+ if (typeof data[0] == "number")
+ data = [data];
+ editor.selection.fromJSON(data.map(function(x) {
+ var start = {row: x[0], column: x[1]};
+ var end = x.length == 2 ? start : {row: x[2], column: x[3]};
+ var isBackwards = Range.comparePoints(start, end) > 0;
+ return isBackwards ? {
+ start: end,
+ end: start,
+ isBackwards: true
+ } : {
+ start: start,
+ end: end,
+ isBackwards: true
+ };
+ }));
+}
+function testSelection(editor, data) {
+ assert.equal(getSelection(editor) + "", data + "");
+}
+function setValue(editor, value) {
+ editor.setValue(value, 1);
+}
+function testValue(editor, value) {
+ assert.equal(editor.getValue(), value);
+}
+
+
+var editor;
+var logEditor;
+var logSession
+exports.openLogView = function() {
+ exports.addGlobals();
+ var sp = window.env.split;
+ sp.setSplits(1);
+ sp.setSplits(2);
+ sp.setOrientation(sp.BESIDE);
+ editor = sp.$editors[0];
+ logEditor = sp.$editors[1];
+
+ if (!logSession) {
+ logSession = new EditSession(localStorage.lastTestCase || "", "ace/mode/javascript");
+ logSession.setUndoManager(new UndoManager)
+ }
+ logEditor.setSession(logSession);
+ logEditor.session.foldAll();
+ logEditor.on("input", save);
+}
+exports.record = function() {
+ exports.addGlobals();
+ exports.openLogView();
+
+ logEditor.setValue("var Range = require(\"ace/range\").Range;\n"
+ + getSelection + "\n"
+ + testSelection + "\n"
+ + setSelection + "\n"
+ + testValue + "\n"
+ + setValue + "\n"
+ + "\n//-------------------------------------\n", 1);
+ logEditor.session.foldAll();
+
+ addAction({
+ type: "setValue",
+ data: editor.getValue()
+ });
+ addAction({
+ type: "setSelection",
+ data: getSelection(editor)
+ });
+ editor.commands.on("afterExec", onAfterExec);
+ editor.on("mouseup", onMouseUp);
+ editor.selection.on("beforeEndOperation", onBeforeEndOperation);
+ editor.session.on("change", reportChange);
+ editor.selection.on("changeCursor", reportCursorChange);
+ editor.selection.on("changeSelection", reportSelectionChange);
+}
+
+exports.stop = function() {
+ save();
+ editor.commands.off("afterExec", onAfterExec);
+ editor.off("mouseup", onMouseUp);
+ editor.off("beforeEndOperation", onBeforeEndOperation);
+ editor.session.off("change", reportChange);
+ editor.selection.off("changeCursor", reportCursorChange);
+ editor.selection.off("changeSelection", reportSelectionChange);
+ logEditor.off("input", save);
+}
+exports.closeLogView = function() {
+ exports.stop();
+ var sp = window.env.split;
+ sp.setSplits(1);
+}
+
+exports.play = function() {
+ exports.openLogView();
+ exports.stop();
+ var code = logEditor ? logEditor.getValue() : localStorage.lastTestCase;
+ var fn = new Function("editor", "debugger;\n" + code);
+ fn(editor);
+}
+var reportChange = reportEvent.bind(null, "change");
+var reportCursorChange = reportEvent.bind(null, "CursorChange");
+var reportSelectionChange = reportEvent.bind(null, "SelectionChange");
+
+function save() {
+ localStorage.lastTestCase = logEditor.getValue();
+}
+
+function reportEvent(name) {
+ addAction({
+ type: "event",
+ source: name
+ });
+}
+function onSelection() {
+ addAction({
+ type: "event",
+ data: "change",
+ source: "operationEnd"
+ });
+}
+function onBeforeEndOperation() {
+ addAction({
+ type: "setSelection",
+ data: getSelection(editor),
+ source: "operationEnd"
+ });
+}
+function onMouseUp() {
+ addAction({
+ type: "setSelection",
+ data: getSelection(editor),
+ source: "mouseup"
+ });
+}
+function onAfterExec(e) {
+ addAction({
+ type: "exec",
+ data: e
+ });
+ addAction({
+ type: "value",
+ data: editor.getValue()
+ });
+ addAction({
+ type: "selection",
+ data: getSelection(editor)
+ });
+}
+
+function addAction(a) {
+ var str = toString(a);
+ if (str) {
+ logEditor.insert(str + "\n");
+ logEditor.renderer.scrollCursorIntoView();
+ }
+}
+
+var lastValue = "";
+function toString(x) {
+ var str = "";
+ var data = x.data;
+ switch (x.type) {
+ case "exec":
+ str = 'editor.execCommand("'
+ + data.command.name
+ + (data.args ? '", ' + JSON.stringify(data.args) : '"')
+ + ')';
+ break;
+ case "setSelection":
+ str = 'setSelection(editor, ' + JSON.stringify(data) + ')';
+ break;
+ case "setValue":
+ if (lastValue != data) {
+ lastValue = data;
+ str = 'editor.setValue(' + JSON.stringify(data) + ', -1)';
+ }
+ else {
+ return;
+ }
+ break;
+ case "selection":
+ str = 'testSelection(editor, ' + JSON.stringify(data) + ')';
+ break;
+ case "value":
+ if (lastValue != data) {
+ lastValue = data;
+ str = 'testValue(editor, ' + JSON.stringify(data) + ')';
+ }
+ else {
+ return;
+ }
+ break;
+ }
+ return str + (x.source ? " // " + x.source : "");
+}
+
+exports.getUI = function(container) {
+ return ["div", {},
+ " Test ",
+ ["button", {onclick: exports.openLogView}, "O"],
+ ["button", {onclick: exports.record}, "Record"],
+ ["button", {onclick: exports.stop}, "Stop"],
+ ["button", {onclick: exports.play}, "Play"],
+ ["button", {onclick: exports.closeLogView}, "X"],
+ ];
+};
+
+
+var ignoreEvents = false;
+exports.textInputDebugger = {
+ position: 2000,
+ path: "textInputDebugger",
+ onchange: function(value) {
+ var sp = env.split;
+ if (sp.getSplits() == 2) {
+ sp.setSplits(1);
+ }
+ if (env.textarea) {
+ if (env.textarea.detach)
+ env.textarea.detach();
+ env.textarea.oldParent.appendChild(env.textarea);
+ env.textarea.className = env.textarea.oldClassName;
+ env.textarea = null;
+ }
+ if (value) {
+ this.showConsole();
+ }
+ },
+ showConsole: function() {
+ var editor = env.split.$editors[0];
+ var text = editor.textInput.getElement();
+ text.oldParent = text.parentNode;
+ text.oldClassName = text.className;
+ text.className = "text-input-debug";
+ document.body.appendChild(text);
+ env.textarea = text;
+
+ var addToLog = function(e) {
+ if (ignoreEvents) return;
+ var data = {
+ _: e.type,
+ range: [text.selectionStart, text.selectionEnd],
+ value: text.value,
+ key: e.key && {
+ code: e.code,
+ key: e.key,
+ keyCode: e.keyCode
+ },
+ modifier: event.getModifierString(e) || undefined
+ };
+ var str = JSON.stringify(data).replace(/"(\w+)":/g, " $1: ");
+ exports.log(str);
+ };
+ var events = ["select", "input", "keypress", "keydown", "keyup",
+ "compositionstart", "compositionupdate", "compositionend", "cut", "copy", "paste"
+ ];
+ events.forEach(function(name) {
+ text.addEventListener(name, addToLog, true);
+ });
+ function onMousedown(ev) {
+ if (ev.domEvent.target == text)
+ ev.$pos = editor.getCursorPosition();
+ }
+ text.detach = function() {
+ delete text.value;
+ delete text.setSelectionRange;
+
+ events.forEach(function(name) {
+ text.removeEventListener(name, addToLog, true);
+ });
+ editor.off("mousedown", onMousedown);
+ };
+ editor.on("mousedown", onMousedown);
+
+ text.__defineSetter__("value", function(v) {
+ this.__proto__.__lookupSetter__("value").call(this, v);
+ console.log(v);
+ });
+ text.__defineGetter__("value", function(v) {
+ var v = this.__proto__.__lookupGetter__("value").call(this);
+ return v;
+ });
+ text.setSelectionRange = function(start, end) {
+ ignoreEvents = true;
+ this.__proto__.setSelectionRange.call(this, start, end)
+ ignoreEvents = false;
+ }
+ exports.openConsole();
+ editor.focus();
+ },
+ getValue: function() {
+ return !!env.textarea;
+ }
+};
+
+exports.textPositionDebugger = {
+ position: 2000,
+ path: "textPositionDebugger",
+ onchange: function(value) {
+ document.body.classList[value ? "add" : "remove"]("show-text-input")
+ },
+ getValue: function() {
+ return document.body.classList.contains("show-text-input");
+ }
+};
+
+exports.openConsole = function() {
+ var sp = env.split;
+ var logEditor = sp.$editors[1];
+ if (!logEditor) {
+ sp.setSplits(2);
+ sp.setOrientation(sp.BELOW);
+ logEditor = sp.$editors[1];
+ }
+ if (!exports.session)
+ exports.session = new EditSession("");
+ logEditor.setSession(exports.session);
+ return logEditor
+};
+exports.log = function(str) {
+ var logEditor = exports.openConsole();
+ logEditor.navigateFileEnd();
+ logEditor.insert(str + ",\n");
+ logEditor.renderer.scrollCursorIntoView();
+};
+
+exports.addGlobals();
+
+});
+
+define("ace/ext/modelist",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+var modes = [];
+function getModeForPath(path) {
+ var mode = modesByName.text;
+ var fileName = path.split(/[\/\\]/).pop();
+ for (var i = 0; i < modes.length; i++) {
+ if (modes[i].supportsFile(fileName)) {
+ mode = modes[i];
+ break;
+ }
+ }
+ return mode;
+}
+
+var Mode = function(name, caption, extensions) {
+ this.name = name;
+ this.caption = caption;
+ this.mode = "ace/mode/" + name;
+ this.extensions = extensions;
+ var re;
+ if (/\^/.test(extensions)) {
+ re = extensions.replace(/\|(\^)?/g, function(a, b){
+ return "$|" + (b ? "^" : "^.*\\.");
+ }) + "$";
+ } else {
+ re = "^.*\\.(" + extensions + ")$";
+ }
+
+ this.extRe = new RegExp(re, "gi");
+};
+
+Mode.prototype.supportsFile = function(filename) {
+ return filename.match(this.extRe);
+};
+var supportedModes = {
+ ABAP: ["abap"],
+ ABC: ["abc"],
+ ActionScript:["as"],
+ ADA: ["ada|adb"],
+ Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],
+ AsciiDoc: ["asciidoc|adoc"],
+ ASL: ["dsl|asl"],
+ Assembly_x86:["asm|a"],
+ AutoHotKey: ["ahk"],
+ Apex: ["apex|cls|trigger|tgr"],
+ AQL: ["aql"],
+ BatchFile: ["bat|cmd"],
+ C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"],
+ C9Search: ["c9search_results"],
+ Crystal: ["cr"],
+ Cirru: ["cirru|cr"],
+ Clojure: ["clj|cljs"],
+ Cobol: ["CBL|COB"],
+ coffee: ["coffee|cf|cson|^Cakefile"],
+ ColdFusion: ["cfm"],
+ CSharp: ["cs"],
+ Csound_Document: ["csd"],
+ Csound_Orchestra: ["orc"],
+ Csound_Score: ["sco"],
+ CSS: ["css"],
+ Curly: ["curly"],
+ D: ["d|di"],
+ Dart: ["dart"],
+ Diff: ["diff|patch"],
+ Dockerfile: ["^Dockerfile"],
+ Dot: ["dot"],
+ Drools: ["drl"],
+ Edifact: ["edi"],
+ Eiffel: ["e|ge"],
+ EJS: ["ejs"],
+ Elixir: ["ex|exs"],
+ Elm: ["elm"],
+ Erlang: ["erl|hrl"],
+ Forth: ["frt|fs|ldr|fth|4th"],
+ Fortran: ["f|f90"],
+ FSharp: ["fsi|fs|ml|mli|fsx|fsscript"],
+ FSL: ["fsl"],
+ FTL: ["ftl"],
+ Gcode: ["gcode"],
+ Gherkin: ["feature"],
+ Gitignore: ["^.gitignore"],
+ Glsl: ["glsl|frag|vert"],
+ Gobstones: ["gbs"],
+ golang: ["go"],
+ GraphQLSchema: ["gql"],
+ Groovy: ["groovy"],
+ HAML: ["haml"],
+ Handlebars: ["hbs|handlebars|tpl|mustache"],
+ Haskell: ["hs"],
+ Haskell_Cabal: ["cabal"],
+ haXe: ["hx"],
+ Hjson: ["hjson"],
+ HTML: ["html|htm|xhtml|vue|we|wpy"],
+ HTML_Elixir: ["eex|html.eex"],
+ HTML_Ruby: ["erb|rhtml|html.erb"],
+ INI: ["ini|conf|cfg|prefs"],
+ Io: ["io"],
+ Jack: ["jack"],
+ Jade: ["jade|pug"],
+ Java: ["java"],
+ JavaScript: ["js|jsm|jsx"],
+ JSON5: ["json5"],
+ JSON: ["json"],
+ JSONiq: ["jq"],
+ JSP: ["jsp"],
+ JSSM: ["jssm|jssm_state"],
+ JSX: ["jsx"],
+ Julia: ["jl"],
+ Kotlin: ["kt|kts"],
+ LaTeX: ["tex|latex|ltx|bib"],
+ LESS: ["less"],
+ Liquid: ["liquid"],
+ Lisp: ["lisp"],
+ LiveScript: ["ls"],
+ LogiQL: ["logic|lql"],
+ LSL: ["lsl"],
+ Lua: ["lua"],
+ LuaPage: ["lp"],
+ Lucene: ["lucene"],
+ Makefile: ["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"],
+ Markdown: ["md|markdown"],
+ Mask: ["mask"],
+ MATLAB: ["matlab"],
+ Maze: ["mz"],
+ MEL: ["mel"],
+ MIXAL: ["mixal"],
+ MUSHCode: ["mc|mush"],
+ MySQL: ["mysql"],
+ Nginx: ["nginx|conf"],
+ Nix: ["nix"],
+ Nim: ["nim"],
+ NSIS: ["nsi|nsh"],
+ Nunjucks: ["nunjucks|nunjs|nj|njk"],
+ ObjectiveC: ["m|mm"],
+ OCaml: ["ml|mli"],
+ Pascal: ["pas|p"],
+ Perl: ["pl|pm"],
+ Perl6: ["p6|pl6|pm6"],
+ pgSQL: ["pgsql"],
+ PHP_Laravel_blade: ["blade.php"],
+ PHP: ["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"],
+ Puppet: ["epp|pp"],
+ Pig: ["pig"],
+ Powershell: ["ps1"],
+ Praat: ["praat|praatscript|psc|proc"],
+ Prolog: ["plg|prolog"],
+ Properties: ["properties"],
+ Protobuf: ["proto"],
+ Python: ["py"],
+ R: ["r"],
+ Razor: ["cshtml|asp"],
+ RDoc: ["Rd"],
+ Red: ["red|reds"],
+ RHTML: ["Rhtml"],
+ RST: ["rst"],
+ Ruby: ["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"],
+ Rust: ["rs"],
+ SASS: ["sass"],
+ SCAD: ["scad"],
+ Scala: ["scala|sbt"],
+ Scheme: ["scm|sm|rkt|oak|scheme"],
+ SCSS: ["scss"],
+ SH: ["sh|bash|^.bashrc"],
+ SJS: ["sjs"],
+ Slim: ["slim|skim"],
+ Smarty: ["smarty|tpl"],
+ snippets: ["snippets"],
+ Soy_Template:["soy"],
+ Space: ["space"],
+ SQL: ["sql"],
+ SQLServer: ["sqlserver"],
+ Stylus: ["styl|stylus"],
+ SVG: ["svg"],
+ Swift: ["swift"],
+ Tcl: ["tcl"],
+ Terraform: ["tf", "tfvars", "terragrunt"],
+ Tex: ["tex"],
+ Text: ["txt"],
+ Textile: ["textile"],
+ Toml: ["toml"],
+ TSX: ["tsx"],
+ Twig: ["latte|twig|swig"],
+ Typescript: ["ts|typescript|str"],
+ Vala: ["vala"],
+ VBScript: ["vbs|vb"],
+ Velocity: ["vm"],
+ Verilog: ["v|vh|sv|svh"],
+ VHDL: ["vhd|vhdl"],
+ Visualforce: ["vfp|component|page"],
+ Wollok: ["wlk|wpgm|wtest"],
+ XML: ["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl|xaml"],
+ XQuery: ["xq"],
+ YAML: ["yaml|yml"],
+ Zeek: ["zeek|bro"],
+ Django: ["html"]
+};
+
+var nameOverrides = {
+ ObjectiveC: "Objective-C",
+ CSharp: "C#",
+ golang: "Go",
+ C_Cpp: "C and C++",
+ Csound_Document: "Csound Document",
+ Csound_Orchestra: "Csound",
+ Csound_Score: "Csound Score",
+ coffee: "CoffeeScript",
+ HTML_Ruby: "HTML (Ruby)",
+ HTML_Elixir: "HTML (Elixir)",
+ FTL: "FreeMarker",
+ PHP_Laravel_blade: "PHP (Blade Template)",
+ Perl6: "Perl 6",
+ AutoHotKey: "AutoHotkey / AutoIt"
+};
+var modesByName = {};
+for (var name in supportedModes) {
+ var data = supportedModes[name];
+ var displayName = (nameOverrides[name] || name).replace(/_/g, " ");
+ var filename = name.toLowerCase();
+ var mode = new Mode(filename, displayName, data[0]);
+ modesByName[filename] = mode;
+ modes.push(mode);
+}
+
+module.exports = {
+ getModeForPath: getModeForPath,
+ modes: modes,
+ modesByName: modesByName
+};
+
+});
+
+define("kitchen-sink/file_drop",["require","exports","module","ace/config","ace/lib/event","ace/ext/modelist","ace/editor"], function(require, exports, module) {
+
+var config = require("ace/config");
+var event = require("ace/lib/event");
+var modelist = require("ace/ext/modelist");
+
+module.exports = function(editor) {
+ event.addListener(editor.container, "dragover", function(e) {
+ var types = e.dataTransfer.types;
+ if (types && Array.prototype.indexOf.call(types, 'Files') !== -1)
+ return event.preventDefault(e);
+ });
+
+ event.addListener(editor.container, "drop", function(e) {
+ var file;
+ try {
+ file = e.dataTransfer.files[0];
+ if (window.FileReader) {
+ var reader = new FileReader();
+ reader.onload = function() {
+ var mode = modelist.getModeForPath(file.name);
+ editor.session.doc.setValue(reader.result);
+ editor.session.setMode(mode.mode);
+ editor.session.modeName = mode.name;
+ };
+ reader.readAsText(file);
+ }
+ return event.preventDefault(e);
+ } catch(err) {
+ return event.stopEvent(e);
+ }
+ });
+};
+
+var Editor = require("ace/editor").Editor;
+config.defineOptions(Editor.prototype, "editor", {
+ loadDroppedFile: {
+ set: function() { module.exports(this); },
+ value: true
+ }
+});
+
+});
+
+define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
+"use strict";
+
+exports.isDark = false;
+exports.cssClass = "ace-tm";
+exports.cssText = ".ace-tm .ace_gutter {\
+background: #f0f0f0;\
+color: #333;\
+}\
+.ace-tm .ace_print-margin {\
+width: 1px;\
+background: #e8e8e8;\
+}\
+.ace-tm .ace_fold {\
+background-color: #6B72E6;\
+}\
+.ace-tm {\
+background-color: #FFFFFF;\
+color: black;\
+}\
+.ace-tm .ace_cursor {\
+color: black;\
+}\
+.ace-tm .ace_invisible {\
+color: rgb(191, 191, 191);\
+}\
+.ace-tm .ace_storage,\
+.ace-tm .ace_keyword {\
+color: blue;\
+}\
+.ace-tm .ace_constant {\
+color: rgb(197, 6, 11);\
+}\
+.ace-tm .ace_constant.ace_buildin {\
+color: rgb(88, 72, 246);\
+}\
+.ace-tm .ace_constant.ace_language {\
+color: rgb(88, 92, 246);\
+}\
+.ace-tm .ace_constant.ace_library {\
+color: rgb(6, 150, 14);\
+}\
+.ace-tm .ace_invalid {\
+background-color: rgba(255, 0, 0, 0.1);\
+color: red;\
+}\
+.ace-tm .ace_support.ace_function {\
+color: rgb(60, 76, 114);\
+}\
+.ace-tm .ace_support.ace_constant {\
+color: rgb(6, 150, 14);\
+}\
+.ace-tm .ace_support.ace_type,\
+.ace-tm .ace_support.ace_class {\
+color: rgb(109, 121, 222);\
+}\
+.ace-tm .ace_keyword.ace_operator {\
+color: rgb(104, 118, 135);\
+}\
+.ace-tm .ace_string {\
+color: rgb(3, 106, 7);\
+}\
+.ace-tm .ace_comment {\
+color: rgb(76, 136, 107);\
+}\
+.ace-tm .ace_comment.ace_doc {\
+color: rgb(0, 102, 255);\
+}\
+.ace-tm .ace_comment.ace_doc.ace_tag {\
+color: rgb(128, 159, 191);\
+}\
+.ace-tm .ace_constant.ace_numeric {\
+color: rgb(0, 0, 205);\
+}\
+.ace-tm .ace_variable {\
+color: rgb(49, 132, 149);\
+}\
+.ace-tm .ace_xml-pe {\
+color: rgb(104, 104, 91);\
+}\
+.ace-tm .ace_entity.ace_name.ace_function {\
+color: #0000A2;\
+}\
+.ace-tm .ace_heading {\
+color: rgb(12, 7, 255);\
+}\
+.ace-tm .ace_list {\
+color:rgb(185, 6, 144);\
+}\
+.ace-tm .ace_meta.ace_tag {\
+color:rgb(0, 22, 142);\
+}\
+.ace-tm .ace_string.ace_regex {\
+color: rgb(255, 0, 0)\
+}\
+.ace-tm .ace_marker-layer .ace_selection {\
+background: rgb(181, 213, 255);\
+}\
+.ace-tm.ace_multiselect .ace_selection.ace_start {\
+box-shadow: 0 0 3px 0px white;\
+}\
+.ace-tm .ace_marker-layer .ace_step {\
+background: rgb(252, 255, 0);\
+}\
+.ace-tm .ace_marker-layer .ace_stack {\
+background: rgb(164, 229, 101);\
+}\
+.ace-tm .ace_marker-layer .ace_bracket {\
+margin: -1px 0 0 -1px;\
+border: 1px solid rgb(192, 192, 192);\
+}\
+.ace-tm .ace_marker-layer .ace_active-line {\
+background: rgba(0, 0, 0, 0.07);\
+}\
+.ace-tm .ace_gutter-active-line {\
+background-color : #dcdcdc;\
+}\
+.ace-tm .ace_marker-layer .ace_selected-word {\
+background: rgb(250, 250, 255);\
+border: 1px solid rgb(200, 200, 250);\
+}\
+.ace-tm .ace_indent-guide {\
+background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
+}\
+";
+exports.$id = "ace/theme/textmate";
+
+var dom = require("../lib/dom");
+dom.importCssString(exports.cssText, exports.cssClass);
+});
+
+define("ace/ext/whitespace",["require","exports","module","ace/lib/lang"], function(require, exports, module) {
+"use strict";
+
+var lang = require("../lib/lang");
+exports.$detectIndentation = function(lines, fallback) {
+ var stats = [];
+ var changes = [];
+ var tabIndents = 0;
+ var prevSpaces = 0;
+ var max = Math.min(lines.length, 1000);
+ for (var i = 0; i < max; i++) {
+ var line = lines[i];
+ if (!/^\s*[^*+\-\s]/.test(line))
+ continue;
+
+ if (line[0] == "\t") {
+ tabIndents++;
+ prevSpaces = -Number.MAX_VALUE;
+ } else {
+ var spaces = line.match(/^ */)[0].length;
+ if (spaces && line[spaces] != "\t") {
+ var diff = spaces - prevSpaces;
+ if (diff > 0 && !(prevSpaces%diff) && !(spaces%diff))
+ changes[diff] = (changes[diff] || 0) + 1;
+
+ stats[spaces] = (stats[spaces] || 0) + 1;
+ }
+ prevSpaces = spaces;
+ }
+ while (i < max && line[line.length - 1] == "\\")
+ line = lines[i++];
+ }
+
+ function getScore(indent) {
+ var score = 0;
+ for (var i = indent; i < stats.length; i += indent)
+ score += stats[i] || 0;
+ return score;
+ }
+
+ var changesTotal = changes.reduce(function(a,b){return a+b;}, 0);
+
+ var first = {score: 0, length: 0};
+ var spaceIndents = 0;
+ for (var i = 1; i < 12; i++) {
+ var score = getScore(i);
+ if (i == 1) {
+ spaceIndents = score;
+ score = stats[1] ? 0.9 : 0.8;
+ if (!stats.length)
+ score = 0;
+ } else
+ score /= spaceIndents;
+
+ if (changes[i])
+ score += changes[i] / changesTotal;
+
+ if (score > first.score)
+ first = {score: score, length: i};
+ }
+
+ if (first.score && first.score > 1.4)
+ var tabLength = first.length;
+
+ if (tabIndents > spaceIndents + 1) {
+ if (tabLength == 1 || spaceIndents < tabIndents / 4 || first.score < 1.8)
+ tabLength = undefined;
+ return {ch: "\t", length: tabLength};
+ }
+ if (spaceIndents > tabIndents + 1)
+ return {ch: " ", length: tabLength};
+};
+
+exports.detectIndentation = function(session) {
+ var lines = session.getLines(0, 1000);
+ var indent = exports.$detectIndentation(lines) || {};
+
+ if (indent.ch)
+ session.setUseSoftTabs(indent.ch == " ");
+
+ if (indent.length)
+ session.setTabSize(indent.length);
+ return indent;
+};
+exports.trimTrailingSpace = function(session, options) {
+ var doc = session.getDocument();
+ var lines = doc.getAllLines();
+
+ var min = options && options.trimEmpty ? -1 : 0;
+ var cursors = [], ci = -1;
+ if (options && options.keepCursorPosition) {
+ if (session.selection.rangeCount) {
+ session.selection.rangeList.ranges.forEach(function(x, i, ranges) {
+ var next = ranges[i + 1];
+ if (next && next.cursor.row == x.cursor.row)
+ return;
+ cursors.push(x.cursor);
+ });
+ } else {
+ cursors.push(session.selection.getCursor());
+ }
+ ci = 0;
+ }
+ var cursorRow = cursors[ci] && cursors[ci].row;
+
+ for (var i = 0, l=lines.length; i < l; i++) {
+ var line = lines[i];
+ var index = line.search(/\s+$/);
+
+ if (i == cursorRow) {
+ if (index < cursors[ci].column && index > min)
+ index = cursors[ci].column;
+ ci++;
+ cursorRow = cursors[ci] ? cursors[ci].row : -1;
+ }
+
+ if (index > min)
+ doc.removeInLine(i, index, line.length);
+ }
+};
+
+exports.convertIndentation = function(session, ch, len) {
+ var oldCh = session.getTabString()[0];
+ var oldLen = session.getTabSize();
+ if (!len) len = oldLen;
+ if (!ch) ch = oldCh;
+
+ var tab = ch == "\t" ? ch: lang.stringRepeat(ch, len);
+
+ var doc = session.doc;
+ var lines = doc.getAllLines();
+
+ var cache = {};
+ var spaceCache = {};
+ for (var i = 0, l=lines.length; i < l; i++) {
+ var line = lines[i];
+ var match = line.match(/^\s*/)[0];
+ if (match) {
+ var w = session.$getStringScreenWidth(match)[0];
+ var tabCount = Math.floor(w/oldLen);
+ var reminder = w%oldLen;
+ var toInsert = cache[tabCount] || (cache[tabCount] = lang.stringRepeat(tab, tabCount));
+ toInsert += spaceCache[reminder] || (spaceCache[reminder] = lang.stringRepeat(" ", reminder));
+
+ if (toInsert != match) {
+ doc.removeInLine(i, 0, match.length);
+ doc.insertInLine({row: i, column: 0}, toInsert);
+ }
+ }
+ }
+ session.setTabSize(len);
+ session.setUseSoftTabs(ch == " ");
+};
+
+exports.$parseStringArg = function(text) {
+ var indent = {};
+ if (/t/.test(text))
+ indent.ch = "\t";
+ else if (/s/.test(text))
+ indent.ch = " ";
+ var m = text.match(/\d+/);
+ if (m)
+ indent.length = parseInt(m[0], 10);
+ return indent;
+};
+
+exports.$parseArg = function(arg) {
+ if (!arg)
+ return {};
+ if (typeof arg == "string")
+ return exports.$parseStringArg(arg);
+ if (typeof arg.text == "string")
+ return exports.$parseStringArg(arg.text);
+ return arg;
+};
+
+exports.commands = [{
+ name: "detectIndentation",
+ description: "Detect indentation from content",
+ exec: function(editor) {
+ exports.detectIndentation(editor.session);
+ }
+}, {
+ name: "trimTrailingSpace",
+ description: "Trim trailing whitespace",
+ exec: function(editor, args) {
+ exports.trimTrailingSpace(editor.session, args);
+ }
+}, {
+ name: "convertIndentation",
+ description: "Convert indentation to ...",
+ exec: function(editor, arg) {
+ var indent = exports.$parseArg(arg);
+ exports.convertIndentation(editor.session, indent.ch, indent.length);
+ }
+}, {
+ name: "setIndentation",
+ description: "Set indentation",
+ exec: function(editor, arg) {
+ var indent = exports.$parseArg(arg);
+ indent.length && editor.session.setTabSize(indent.length);
+ indent.ch && editor.session.setUseSoftTabs(indent.ch == " ");
+ }
+}];
+
+});
+
+define("kitchen-sink/doclist",["require","exports","module","ace/edit_session","ace/undomanager","ace/lib/net","ace/ext/modelist"], function(require, exports, module) {
+"use strict";
+
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+var net = require("ace/lib/net");
+
+var modelist = require("ace/ext/modelist");
+var fileCache = {};
+
+function initDoc(file, path, doc) {
+ if (doc.prepare)
+ file = doc.prepare(file);
+
+ var session = new EditSession(file);
+ session.setUndoManager(new UndoManager());
+ doc.session = session;
+ doc.path = path;
+ session.name = doc.name;
+ if (doc.wrapped) {
+ session.setUseWrapMode(true);
+ session.setWrapLimitRange(80, 80);
+ }
+ var mode = modelist.getModeForPath(path);
+ session.modeName = mode.name;
+ session.setMode(mode.mode);
+ return session;
+}
+
+
+function makeHuge(txt) {
+ for (var i = 0; i < 5; i++)
+ txt += txt;
+ return txt;
+}
+
+var docs = {
+ "docs/javascript.js": {order: 1, name: "JavaScript"},
+
+ "docs/latex.tex": {name: "LaTeX", wrapped: true},
+ "docs/markdown.md": {name: "Markdown", wrapped: true},
+ "docs/mushcode.mc": {name: "MUSHCode", wrapped: true},
+ "docs/pgsql.pgsql": {name: "pgSQL", wrapped: true},
+ "docs/plaintext.txt": {name: "Plain Text", prepare: makeHuge, wrapped: true},
+ "docs/sql.sql": {name: "SQL", wrapped: true},
+
+ "docs/textile.textile": {name: "Textile", wrapped: true},
+
+ "docs/c9search.c9search_results": "C9 Search Results",
+ "docs/mel.mel": "MEL",
+ "docs/Nix.nix": "Nix"
+};
+
+var ownSource = {
+};
+
+var hugeDocs = require.toUrl ? {
+ "build/src/ace.js": "",
+ "build/src-min/ace.js": ""
+} : {
+ "src/ace.js": "",
+ "src-min/ace.js": ""
+};
+
+modelist.modes.forEach(function(m) {
+ var ext = m.extensions.split("|")[0];
+ if (ext[0] === "^") {
+ path = ext.substr(1);
+ } else {
+ var path = m.name + "." + ext;
+ }
+ path = "docs/" + path;
+ if (!docs[path]) {
+ docs[path] = {name: m.caption};
+ } else if (typeof docs[path] == "object" && !docs[path].name) {
+ docs[path].name = m.caption;
+ }
+});
+
+
+
+if (window.require && window.require.s) try {
+ for (var path in window.require.s.contexts._.defined) {
+ if (path.indexOf("!") != -1)
+ path = path.split("!").pop();
+ else
+ path = path + ".js";
+ ownSource[path] = "";
+ }
+} catch(e) {}
+
+function sort(list) {
+ return list.sort(function(a, b) {
+ var cmp = (b.order || 0) - (a.order || 0);
+ return cmp || a.name && a.name.localeCompare(b.name);
+ });
+}
+
+function prepareDocList(docs) {
+ var list = [];
+ for (var path in docs) {
+ var doc = docs[path];
+ if (typeof doc != "object")
+ doc = {name: doc || path};
+
+ doc.path = path;
+ doc.desc = doc.name.replace(/^(ace|docs|demo|build)\//, "");
+ if (doc.desc.length > 18)
+ doc.desc = doc.desc.slice(0, 7) + ".." + doc.desc.slice(-9);
+
+ fileCache[doc.name.toLowerCase()] = doc;
+ list.push(doc);
+ }
+
+ return list;
+}
+
+function loadDoc(name, callback) {
+ var doc = fileCache[name.toLowerCase()];
+ if (!doc)
+ return callback(null);
+
+ if (doc.session)
+ return callback(doc.session);
+ var path = doc.path;
+ var parts = path.split("/");
+ if (parts[0] == "docs")
+ path = "demo/kitchen-sink/" + path;
+ else if (parts[0] == "ace")
+ path = "lib/" + path;
+
+ net.get(path, function(x) {
+ initDoc(x, path, doc);
+ callback(doc.session);
+ });
+}
+
+function saveDoc(name, callback) {
+ var doc = fileCache[name.toLowerCase()] || name;
+ if (!doc || !doc.session)
+ return callback("Unknown document: " + name);
+
+ var path = doc.path;
+ var parts = path.split("/");
+ if (parts[0] == "docs")
+ path = "demo/kitchen-sink/" + path;
+ else if (parts[0] == "ace")
+ path = "lib/" + path;
+
+ upload(path, doc.session.getValue(), callback);
+}
+
+function upload(url, data, callback) {
+ var absUrl = net.qualifyURL(url);
+ if (/^file:/.test(absUrl))
+ absUrl = "http://localhost:8888/" + url;
+ url = absUrl;
+ if (!/^https?:/.test(url))
+ return callback(new Error("Unsupported url scheme"));
+ var xhr = new XMLHttpRequest();
+ xhr.open("PUT", url, true);
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ callback(!/^2../.test(xhr.status));
+ }
+ };
+ xhr.send(data);
+}
+
+module.exports = {
+ fileCache: fileCache,
+ docs: sort(prepareDocList(docs)),
+ ownSource: prepareDocList(ownSource),
+ hugeDocs: prepareDocList(hugeDocs),
+ initDoc: initDoc,
+ loadDoc: loadDoc,
+ saveDoc: saveDoc
+};
+module.exports.all = {
+ "Mode Examples": module.exports.docs,
+ "Huge documents": module.exports.hugeDocs,
+ "own source": module.exports.ownSource
+};
+
+});
+
+define("kitchen-sink/layout",["require","exports","module","ace/lib/dom","ace/lib/event","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/editor","ace/multi_select","ace/theme/textmate"], function(require, exports, module) {
+"use strict";
+
+var dom = require("ace/lib/dom");
+var event = require("ace/lib/event");
+
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+var Renderer = require("ace/virtual_renderer").VirtualRenderer;
+var Editor = require("ace/editor").Editor;
+var MultiSelect = require("ace/multi_select").MultiSelect;
+
+dom.importCssString("\
+splitter {\
+ border: 1px solid #C6C6D2;\
+ width: 0px;\
+ cursor: ew-resize;\
+ z-index:10}\
+splitter:hover {\
+ margin-left: -2px;\
+ width:3px;\
+ border-color: #B5B4E0;\
+}\
+", "splitEditor");
+
+exports.edit = function(el) {
+ if (typeof(el) == "string")
+ el = document.getElementById(el);
+
+ var editor = new Editor(new Renderer(el, require("ace/theme/textmate")));
+
+ editor.resize();
+ event.addListener(window, "resize", function() {
+ editor.resize();
+ });
+ return editor;
+};
+
+
+var SplitRoot = function(el, theme, position, getSize) {
+ el.style.position = position || "relative";
+ this.container = el;
+ this.getSize = getSize || this.getSize;
+ this.resize = this.$resize.bind(this);
+
+ event.addListener(el.ownerDocument.defaultView, "resize", this.resize);
+ this.editor = this.createEditor();
+};
+
+(function(){
+ this.createEditor = function() {
+ var el = document.createElement("div");
+ el.className = this.$editorCSS;
+ el.style.cssText = "position: absolute; top:0px; bottom:0px";
+ this.$container.appendChild(el);
+ var session = new EditSession("");
+ var editor = new Editor(new Renderer(el, this.$theme));
+
+ this.$editors.push(editor);
+ editor.setFontSize(this.$fontSize);
+ return editor;
+ };
+ this.$resize = function() {
+ var size = this.getSize(this.container);
+ this.rect = {
+ x: size.left,
+ y: size.top,
+ w: size.width,
+ h: size.height
+ };
+ this.item.resize(this.rect);
+ };
+ this.getSize = function(el) {
+ return el.getBoundingClientRect();
+ };
+ this.destroy = function() {
+ var win = this.container.ownerDocument.defaultView;
+ event.removeListener(win, "resize", this.resize);
+ };
+
+
+}).call(SplitRoot.prototype);
+
+
+
+var Split = function(){
+
+};
+(function(){
+ this.execute = function(options) {
+ this.$u.execute(options);
+ };
+
+}).call(Split.prototype);
+
+
+
+exports.singleLineEditor = function(el) {
+ var renderer = new Renderer(el);
+ el.style.overflow = "hidden";
+
+ renderer.screenToTextCoordinates = function(x, y) {
+ var pos = this.pixelToScreenCoordinates(x, y);
+ return this.session.screenToDocumentPosition(
+ Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)),
+ Math.max(pos.column, 0)
+ );
+ };
+
+ renderer.$maxLines = 4;
+
+ renderer.setStyle("ace_one-line");
+ var editor = new Editor(renderer);
+ editor.session.setUndoManager(new UndoManager());
+
+ editor.setShowPrintMargin(false);
+ editor.renderer.setShowGutter(false);
+ editor.renderer.setHighlightGutterLine(false);
+ editor.$mouseHandler.$focusWaitTimout = 0;
+
+ return editor;
+};
+
+
+
+});
+
+define("kitchen-sink/util",["require","exports","module","ace/lib/dom","ace/lib/event","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/editor","ace/multi_select"], function(require, exports, module) {
+"use strict";
+
+var dom = require("ace/lib/dom");
+var event = require("ace/lib/event");
+
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+var Renderer = require("ace/virtual_renderer").VirtualRenderer;
+var Editor = require("ace/editor").Editor;
+var MultiSelect = require("ace/multi_select").MultiSelect;
+
+var urlOptions = {}
+try {
+ window.location.search.slice(1).split(/[&]/).forEach(function(e) {
+ var parts = e.split("=");
+ urlOptions[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ });
+} catch(e) {
+ console.error(e);
+}
+exports.createEditor = function(el) {
+ return new Editor(new Renderer(el));
+};
+
+exports.getOption = function(name) {
+ if (urlOptions[name])
+ return urlOptions[name];
+ return localStorage && localStorage.getItem(name);
+};
+
+exports.saveOption = function(name, value) {
+ if (value == false)
+ value = "";
+ localStorage && localStorage.setItem(name, value);
+};
+
+exports.createSplitEditor = function(el) {
+ if (typeof(el) == "string")
+ el = document.getElementById(el);
+
+ var e0 = document.createElement("div");
+ var s = document.createElement("splitter");
+ var e1 = document.createElement("div");
+ el.appendChild(e0);
+ el.appendChild(e1);
+ el.appendChild(s);
+ e0.style.position = e1.style.position = s.style.position = "absolute";
+ el.style.position = "relative";
+ var split = {$container: el};
+
+ split.editor0 = split[0] = new Editor(new Renderer(e0));
+ split.editor1 = split[1] = new Editor(new Renderer(e1));
+ split.splitter = s;
+
+ s.ratio = 0.5;
+
+ split.resize = function resize(){
+ var height = el.parentNode.clientHeight - el.offsetTop;
+ var total = el.clientWidth;
+ var w1 = total * s.ratio;
+ var w2 = total * (1- s.ratio);
+ s.style.left = w1 - 1 + "px";
+ s.style.height = el.style.height = height + "px";
+
+ var st0 = split[0].container.style;
+ var st1 = split[1].container.style;
+ st0.width = w1 + "px";
+ st1.width = w2 + "px";
+ st0.left = 0 + "px";
+ st1.left = w1 + "px";
+
+ st0.top = st1.top = "0px";
+ st0.height = st1.height = height + "px";
+
+ split[0].resize();
+ split[1].resize();
+ };
+
+ split.onMouseDown = function(e) {
+ var rect = el.getBoundingClientRect();
+ var x = e.clientX;
+ var y = e.clientY;
+
+ var button = e.button;
+ if (button !== 0) {
+ return;
+ }
+
+ var onMouseMove = function(e) {
+ x = e.clientX;
+ y = e.clientY;
+ };
+ var onResizeEnd = function(e) {
+ clearInterval(timerId);
+ };
+
+ var onResizeInterval = function() {
+ s.ratio = (x - rect.left) / rect.width;
+ split.resize();
+ };
+
+ event.capture(s, onMouseMove, onResizeEnd);
+ var timerId = setInterval(onResizeInterval, 40);
+
+ return e.preventDefault();
+ };
+
+
+
+ event.addListener(s, "mousedown", split.onMouseDown);
+ event.addListener(window, "resize", split.resize);
+ split.resize();
+ return split;
+};
+exports.stripLeadingComments = function(str) {
+ if(str.slice(0,2)=='/*') {
+ var j = str.indexOf('*/')+2;
+ str = str.substr(j);
+ }
+ return str.trim() + "\n";
+};
+function saveOptionFromElement(el, val) {
+ if (!el.onchange && !el.onclick)
+ return;
+
+ if ("checked" in el) {
+ localStorage && localStorage.setItem(el.id, el.checked ? 1 : 0);
+ }
+ else {
+ localStorage && localStorage.setItem(el.id, el.value);
+ }
+}
+
+exports.bindCheckbox = function(id, callback, noInit) {
+ if (typeof id == "string")
+ var el = document.getElementById(id);
+ else {
+ var el = id;
+ id = el.id;
+ }
+ var el = document.getElementById(id);
+
+ if (urlOptions[id])
+ el.checked = urlOptions[id] == "1";
+ else if (localStorage && localStorage.getItem(id))
+ el.checked = localStorage.getItem(id) == "1";
+
+ var onCheck = function() {
+ callback(!!el.checked);
+ saveOptionFromElement(el);
+ };
+ el.onclick = onCheck;
+ noInit || onCheck();
+ return el;
+};
+
+exports.bindDropdown = function(id, callback, noInit) {
+ if (typeof id == "string")
+ var el = document.getElementById(id);
+ else {
+ var el = id;
+ id = el.id;
+ }
+
+ if (urlOptions[id])
+ el.value = urlOptions[id];
+ else if (localStorage && localStorage.getItem(id))
+ el.value = localStorage.getItem(id);
+
+ var onChange = function() {
+ callback(el.value);
+ saveOptionFromElement(el);
+ };
+
+ el.onchange = onChange;
+ noInit || onChange();
+};
+
+exports.fillDropdown = function(el, values) {
+ if (typeof el == "string")
+ el = document.getElementById(el);
+
+ dropdown(values).forEach(function(e) {
+ el.appendChild(e);
+ });
+};
+
+function elt(tag, attributes, content) {
+ var el = dom.createElement(tag);
+ if (typeof content == "string") {
+ el.appendChild(document.createTextNode(content));
+ } else if (content) {
+ content.forEach(function(ch) {
+ el.appendChild(ch);
+ });
+ }
+
+ for (var i in attributes)
+ el.setAttribute(i, attributes[i]);
+ return el;
+}
+
+function optgroup(values) {
+ return values.map(function(item) {
+ if (typeof item == "string")
+ item = {name: item, caption: item};
+ return elt("option", {value: item.value || item.name}, item.caption || item.desc);
+ });
+}
+
+function dropdown(values) {
+ if (Array.isArray(values))
+ return optgroup(values);
+
+ return Object.keys(values).map(function(i) {
+ return elt("optgroup", {"label": i}, optgroup(values[i]));
+ });
+}
+
+
+});
+
+define("ace/ext/elastic_tabstops_lite",["require","exports","module","ace/editor","ace/config"], function(require, exports, module) {
+"use strict";
+
+var ElasticTabstopsLite = function(editor) {
+ this.$editor = editor;
+ var self = this;
+ var changedRows = [];
+ var recordChanges = false;
+ this.onAfterExec = function() {
+ recordChanges = false;
+ self.processRows(changedRows);
+ changedRows = [];
+ };
+ this.onExec = function() {
+ recordChanges = true;
+ };
+ this.onChange = function(delta) {
+ if (recordChanges) {
+ if (changedRows.indexOf(delta.start.row) == -1)
+ changedRows.push(delta.start.row);
+ if (delta.end.row != delta.start.row)
+ changedRows.push(delta.end.row);
+ }
+ };
+};
+
+(function() {
+ this.processRows = function(rows) {
+ this.$inChange = true;
+ var checkedRows = [];
+
+ for (var r = 0, rowCount = rows.length; r < rowCount; r++) {
+ var row = rows[r];
+
+ if (checkedRows.indexOf(row) > -1)
+ continue;
+
+ var cellWidthObj = this.$findCellWidthsForBlock(row);
+ var cellWidths = this.$setBlockCellWidthsToMax(cellWidthObj.cellWidths);
+ var rowIndex = cellWidthObj.firstRow;
+
+ for (var w = 0, l = cellWidths.length; w < l; w++) {
+ var widths = cellWidths[w];
+ checkedRows.push(rowIndex);
+ this.$adjustRow(rowIndex, widths);
+ rowIndex++;
+ }
+ }
+ this.$inChange = false;
+ };
+
+ this.$findCellWidthsForBlock = function(row) {
+ var cellWidths = [], widths;
+ var rowIter = row;
+ while (rowIter >= 0) {
+ widths = this.$cellWidthsForRow(rowIter);
+ if (widths.length == 0)
+ break;
+
+ cellWidths.unshift(widths);
+ rowIter--;
+ }
+ var firstRow = rowIter + 1;
+ rowIter = row;
+ var numRows = this.$editor.session.getLength();
+
+ while (rowIter < numRows - 1) {
+ rowIter++;
+
+ widths = this.$cellWidthsForRow(rowIter);
+ if (widths.length == 0)
+ break;
+
+ cellWidths.push(widths);
+ }
+
+ return { cellWidths: cellWidths, firstRow: firstRow };
+ };
+
+ this.$cellWidthsForRow = function(row) {
+ var selectionColumns = this.$selectionColumnsForRow(row);
+
+ var tabs = [-1].concat(this.$tabsForRow(row));
+ var widths = tabs.map(function(el) { return 0; } ).slice(1);
+ var line = this.$editor.session.getLine(row);
+
+ for (var i = 0, len = tabs.length - 1; i < len; i++) {
+ var leftEdge = tabs[i]+1;
+ var rightEdge = tabs[i+1];
+
+ var rightmostSelection = this.$rightmostSelectionInCell(selectionColumns, rightEdge);
+ var cell = line.substring(leftEdge, rightEdge);
+ widths[i] = Math.max(cell.replace(/\s+$/g,'').length, rightmostSelection - leftEdge);
+ }
+
+ return widths;
+ };
+
+ this.$selectionColumnsForRow = function(row) {
+ var selections = [], cursor = this.$editor.getCursorPosition();
+ if (this.$editor.session.getSelection().isEmpty()) {
+ if (row == cursor.row)
+ selections.push(cursor.column);
+ }
+
+ return selections;
+ };
+
+ this.$setBlockCellWidthsToMax = function(cellWidths) {
+ var startingNewBlock = true, blockStartRow, blockEndRow, maxWidth;
+ var columnInfo = this.$izip_longest(cellWidths);
+
+ for (var c = 0, l = columnInfo.length; c < l; c++) {
+ var column = columnInfo[c];
+ if (!column.push) {
+ console.error(column);
+ continue;
+ }
+ column.push(NaN);
+
+ for (var r = 0, s = column.length; r < s; r++) {
+ var width = column[r];
+ if (startingNewBlock) {
+ blockStartRow = r;
+ maxWidth = 0;
+ startingNewBlock = false;
+ }
+ if (isNaN(width)) {
+ blockEndRow = r;
+
+ for (var j = blockStartRow; j < blockEndRow; j++) {
+ cellWidths[j][c] = maxWidth;
+ }
+ startingNewBlock = true;
+ }
+
+ maxWidth = Math.max(maxWidth, width);
+ }
+ }
+
+ return cellWidths;
+ };
+
+ this.$rightmostSelectionInCell = function(selectionColumns, cellRightEdge) {
+ var rightmost = 0;
+
+ if (selectionColumns.length) {
+ var lengths = [];
+ for (var s = 0, length = selectionColumns.length; s < length; s++) {
+ if (selectionColumns[s] <= cellRightEdge)
+ lengths.push(s);
+ else
+ lengths.push(0);
+ }
+ rightmost = Math.max.apply(Math, lengths);
+ }
+
+ return rightmost;
+ };
+
+ this.$tabsForRow = function(row) {
+ var rowTabs = [], line = this.$editor.session.getLine(row),
+ re = /\t/g, match;
+
+ while ((match = re.exec(line)) != null) {
+ rowTabs.push(match.index);
+ }
+
+ return rowTabs;
+ };
+
+ this.$adjustRow = function(row, widths) {
+ var rowTabs = this.$tabsForRow(row);
+
+ if (rowTabs.length == 0)
+ return;
+
+ var bias = 0, location = -1;
+ var expandedSet = this.$izip(widths, rowTabs);
+
+ for (var i = 0, l = expandedSet.length; i < l; i++) {
+ var w = expandedSet[i][0], it = expandedSet[i][1];
+ location += 1 + w;
+ it += bias;
+ var difference = location - it;
+
+ if (difference == 0)
+ continue;
+
+ var partialLine = this.$editor.session.getLine(row).substr(0, it );
+ var strippedPartialLine = partialLine.replace(/\s*$/g, "");
+ var ispaces = partialLine.length - strippedPartialLine.length;
+
+ if (difference > 0) {
+ this.$editor.session.getDocument().insertInLine({row: row, column: it + 1}, Array(difference + 1).join(" ") + "\t");
+ this.$editor.session.getDocument().removeInLine(row, it, it + 1);
+
+ bias += difference;
+ }
+
+ if (difference < 0 && ispaces >= -difference) {
+ this.$editor.session.getDocument().removeInLine(row, it + difference, it);
+ bias += difference;
+ }
+ }
+ };
+ this.$izip_longest = function(iterables) {
+ if (!iterables[0])
+ return [];
+ var longest = iterables[0].length;
+ var iterablesLength = iterables.length;
+
+ for (var i = 1; i < iterablesLength; i++) {
+ var iLength = iterables[i].length;
+ if (iLength > longest)
+ longest = iLength;
+ }
+
+ var expandedSet = [];
+
+ for (var l = 0; l < longest; l++) {
+ var set = [];
+ for (var i = 0; i < iterablesLength; i++) {
+ if (iterables[i][l] === "")
+ set.push(NaN);
+ else
+ set.push(iterables[i][l]);
+ }
+
+ expandedSet.push(set);
+ }
+
+
+ return expandedSet;
+ };
+ this.$izip = function(widths, tabs) {
+ var size = widths.length >= tabs.length ? tabs.length : widths.length;
+
+ var expandedSet = [];
+ for (var i = 0; i < size; i++) {
+ var set = [ widths[i], tabs[i] ];
+ expandedSet.push(set);
+ }
+ return expandedSet;
+ };
+
+}).call(ElasticTabstopsLite.prototype);
+
+exports.ElasticTabstopsLite = ElasticTabstopsLite;
+
+var Editor = require("../editor").Editor;
+require("../config").defineOptions(Editor.prototype, "editor", {
+ useElasticTabstops: {
+ set: function(val) {
+ if (val) {
+ if (!this.elasticTabstops)
+ this.elasticTabstops = new ElasticTabstopsLite(this);
+ this.commands.on("afterExec", this.elasticTabstops.onAfterExec);
+ this.commands.on("exec", this.elasticTabstops.onExec);
+ this.on("change", this.elasticTabstops.onChange);
+ } else if (this.elasticTabstops) {
+ this.commands.removeListener("afterExec", this.elasticTabstops.onAfterExec);
+ this.commands.removeListener("exec", this.elasticTabstops.onExec);
+ this.removeListener("change", this.elasticTabstops.onChange);
+ }
+ }
+ }
+});
+
+});
+
+define("ace/occur",["require","exports","module","ace/lib/oop","ace/range","ace/search","ace/edit_session","ace/search_highlight","ace/lib/dom"], function(require, exports, module) {
+"use strict";
+
+var oop = require("./lib/oop");
+var Range = require("./range").Range;
+var Search = require("./search").Search;
+var EditSession = require("./edit_session").EditSession;
+var SearchHighlight = require("./search_highlight").SearchHighlight;
+function Occur() {}
+
+oop.inherits(Occur, Search);
+
+(function() {
+ this.enter = function(editor, options) {
+ if (!options.needle) return false;
+ var pos = editor.getCursorPosition();
+ this.displayOccurContent(editor, options);
+ var translatedPos = this.originalToOccurPosition(editor.session, pos);
+ editor.moveCursorToPosition(translatedPos);
+ return true;
+ };
+ this.exit = function(editor, options) {
+ var pos = options.translatePosition && editor.getCursorPosition();
+ var translatedPos = pos && this.occurToOriginalPosition(editor.session, pos);
+ this.displayOriginalContent(editor);
+ if (translatedPos)
+ editor.moveCursorToPosition(translatedPos);
+ return true;
+ };
+
+ this.highlight = function(sess, regexp) {
+ var hl = sess.$occurHighlight = sess.$occurHighlight || sess.addDynamicMarker(
+ new SearchHighlight(null, "ace_occur-highlight", "text"));
+ hl.setRegexp(regexp);
+ sess._emit("changeBackMarker"); // force highlight layer redraw
+ };
+
+ this.displayOccurContent = function(editor, options) {
+ this.$originalSession = editor.session;
+ var found = this.matchingLines(editor.session, options);
+ var lines = found.map(function(foundLine) { return foundLine.content; });
+ var occurSession = new EditSession(lines.join('\n'));
+ occurSession.$occur = this;
+ occurSession.$occurMatchingLines = found;
+ editor.setSession(occurSession);
+ this.$useEmacsStyleLineStart = this.$originalSession.$useEmacsStyleLineStart;
+ occurSession.$useEmacsStyleLineStart = this.$useEmacsStyleLineStart;
+ this.highlight(occurSession, options.re);
+ occurSession._emit('changeBackMarker');
+ };
+
+ this.displayOriginalContent = function(editor) {
+ editor.setSession(this.$originalSession);
+ this.$originalSession.$useEmacsStyleLineStart = this.$useEmacsStyleLineStart;
+ };
+ this.originalToOccurPosition = function(session, pos) {
+ var lines = session.$occurMatchingLines;
+ var nullPos = {row: 0, column: 0};
+ if (!lines) return nullPos;
+ for (var i = 0; i < lines.length; i++) {
+ if (lines[i].row === pos.row)
+ return {row: i, column: pos.column};
+ }
+ return nullPos;
+ };
+ this.occurToOriginalPosition = function(session, pos) {
+ var lines = session.$occurMatchingLines;
+ if (!lines || !lines[pos.row])
+ return pos;
+ return {row: lines[pos.row].row, column: pos.column};
+ };
+
+ this.matchingLines = function(session, options) {
+ options = oop.mixin({}, options);
+ if (!session || !options.needle) return [];
+ var search = new Search();
+ search.set(options);
+ return search.findAll(session).reduce(function(lines, range) {
+ var row = range.start.row;
+ var last = lines[lines.length-1];
+ return last && last.row === row ?
+ lines :
+ lines.concat({row: row, content: session.getLine(row)});
+ }, []);
+ };
+
+}).call(Occur.prototype);
+
+var dom = require('./lib/dom');
+dom.importCssString(".ace_occur-highlight {\n\
+ border-radius: 4px;\n\
+ background-color: rgba(87, 255, 8, 0.25);\n\
+ position: absolute;\n\
+ z-index: 4;\n\
+ box-sizing: border-box;\n\
+ box-shadow: 0 0 4px rgb(91, 255, 50);\n\
+}\n\
+.ace_dark .ace_occur-highlight {\n\
+ background-color: rgb(80, 140, 85);\n\
+ box-shadow: 0 0 4px rgb(60, 120, 70);\n\
+}\n", "incremental-occur-highlighting");
+
+exports.Occur = Occur;
+
+});
+
+define("ace/commands/occur_commands",["require","exports","module","ace/config","ace/occur","ace/keyboard/hash_handler","ace/lib/oop"], function(require, exports, module) {
+
+var config = require("../config"),
+ Occur = require("../occur").Occur;
+var occurStartCommand = {
+ name: "occur",
+ exec: function(editor, options) {
+ var alreadyInOccur = !!editor.session.$occur;
+ var occurSessionActive = new Occur().enter(editor, options);
+ if (occurSessionActive && !alreadyInOccur)
+ OccurKeyboardHandler.installIn(editor);
+ },
+ readOnly: true
+};
+
+var occurCommands = [{
+ name: "occurexit",
+ bindKey: 'esc|Ctrl-G',
+ exec: function(editor) {
+ var occur = editor.session.$occur;
+ if (!occur) return;
+ occur.exit(editor, {});
+ if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor);
+ },
+ readOnly: true
+}, {
+ name: "occuraccept",
+ bindKey: 'enter',
+ exec: function(editor) {
+ var occur = editor.session.$occur;
+ if (!occur) return;
+ occur.exit(editor, {translatePosition: true});
+ if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor);
+ },
+ readOnly: true
+}];
+
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var oop = require("../lib/oop");
+
+
+function OccurKeyboardHandler() {}
+
+oop.inherits(OccurKeyboardHandler, HashHandler);
+
+(function() {
+
+ this.isOccurHandler = true;
+
+ this.attach = function(editor) {
+ HashHandler.call(this, occurCommands, editor.commands.platform);
+ this.$editor = editor;
+ };
+
+ var handleKeyboard$super = this.handleKeyboard;
+ this.handleKeyboard = function(data, hashId, key, keyCode) {
+ var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode);
+ return (cmd && cmd.command) ? cmd : undefined;
+ };
+
+}).call(OccurKeyboardHandler.prototype);
+
+OccurKeyboardHandler.installIn = function(editor) {
+ var handler = new this();
+ editor.keyBinding.addKeyboardHandler(handler);
+ editor.commands.addCommands(occurCommands);
+};
+
+OccurKeyboardHandler.uninstallFrom = function(editor) {
+ editor.commands.removeCommands(occurCommands);
+ var handler = editor.getKeyboardHandler();
+ if (handler.isOccurHandler)
+ editor.keyBinding.removeKeyboardHandler(handler);
+};
+
+exports.occurStartCommand = occurStartCommand;
+
+});
+
+define("ace/commands/incremental_search_commands",["require","exports","module","ace/config","ace/lib/oop","ace/keyboard/hash_handler","ace/commands/occur_commands"], function(require, exports, module) {
+
+var config = require("../config");
+var oop = require("../lib/oop");
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var occurStartCommand = require("./occur_commands").occurStartCommand;
+exports.iSearchStartCommands = [{
+ name: "iSearch",
+ bindKey: {win: "Ctrl-F", mac: "Command-F"},
+ exec: function(editor, options) {
+ config.loadModule(["core", "ace/incremental_search"], function(e) {
+ var iSearch = e.iSearch = e.iSearch || new e.IncrementalSearch();
+ iSearch.activate(editor, options.backwards);
+ if (options.jumpToFirstMatch) iSearch.next(options);
+ });
+ },
+ readOnly: true
+}, {
+ name: "iSearchBackwards",
+ exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {backwards: true}); },
+ readOnly: true
+}, {
+ name: "iSearchAndGo",
+ bindKey: {win: "Ctrl-K", mac: "Command-G"},
+ exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {jumpToFirstMatch: true, useCurrentOrPrevSearch: true}); },
+ readOnly: true
+}, {
+ name: "iSearchBackwardsAndGo",
+ bindKey: {win: "Ctrl-Shift-K", mac: "Command-Shift-G"},
+ exec: function(editor) { editor.execCommand('iSearch', {jumpToFirstMatch: true, backwards: true, useCurrentOrPrevSearch: true}); },
+ readOnly: true
+}];
+exports.iSearchCommands = [{
+ name: "restartSearch",
+ bindKey: {win: "Ctrl-F", mac: "Command-F"},
+ exec: function(iSearch) {
+ iSearch.cancelSearch(true);
+ }
+}, {
+ name: "searchForward",
+ bindKey: {win: "Ctrl-S|Ctrl-K", mac: "Ctrl-S|Command-G"},
+ exec: function(iSearch, options) {
+ options.useCurrentOrPrevSearch = true;
+ iSearch.next(options);
+ }
+}, {
+ name: "searchBackward",
+ bindKey: {win: "Ctrl-R|Ctrl-Shift-K", mac: "Ctrl-R|Command-Shift-G"},
+ exec: function(iSearch, options) {
+ options.useCurrentOrPrevSearch = true;
+ options.backwards = true;
+ iSearch.next(options);
+ }
+}, {
+ name: "extendSearchTerm",
+ exec: function(iSearch, string) {
+ iSearch.addString(string);
+ }
+}, {
+ name: "extendSearchTermSpace",
+ bindKey: "space",
+ exec: function(iSearch) { iSearch.addString(' '); }
+}, {
+ name: "shrinkSearchTerm",
+ bindKey: "backspace",
+ exec: function(iSearch) {
+ iSearch.removeChar();
+ }
+}, {
+ name: 'confirmSearch',
+ bindKey: 'return',
+ exec: function(iSearch) { iSearch.deactivate(); }
+}, {
+ name: 'cancelSearch',
+ bindKey: 'esc|Ctrl-G',
+ exec: function(iSearch) { iSearch.deactivate(true); }
+}, {
+ name: 'occurisearch',
+ bindKey: 'Ctrl-O',
+ exec: function(iSearch) {
+ var options = oop.mixin({}, iSearch.$options);
+ iSearch.deactivate();
+ occurStartCommand.exec(iSearch.$editor, options);
+ }
+}, {
+ name: "yankNextWord",
+ bindKey: "Ctrl-w",
+ exec: function(iSearch) {
+ var ed = iSearch.$editor,
+ range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorWordRight(); }),
+ string = ed.session.getTextRange(range);
+ iSearch.addString(string);
+ }
+}, {
+ name: "yankNextChar",
+ bindKey: "Ctrl-Alt-y",
+ exec: function(iSearch) {
+ var ed = iSearch.$editor,
+ range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorRight(); }),
+ string = ed.session.getTextRange(range);
+ iSearch.addString(string);
+ }
+}, {
+ name: 'recenterTopBottom',
+ bindKey: 'Ctrl-l',
+ exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); }
+}, {
+ name: 'selectAllMatches',
+ bindKey: 'Ctrl-space',
+ exec: function(iSearch) {
+ var ed = iSearch.$editor,
+ hl = ed.session.$isearchHighlight,
+ ranges = hl && hl.cache ? hl.cache
+ .reduce(function(ranges, ea) {
+ return ranges.concat(ea ? ea : []); }, []) : [];
+ iSearch.deactivate(false);
+ ranges.forEach(ed.selection.addRange.bind(ed.selection));
+ }
+}, {
+ name: 'searchAsRegExp',
+ bindKey: 'Alt-r',
+ exec: function(iSearch) {
+ iSearch.convertNeedleToRegExp();
+ }
+}].map(function(cmd) {
+ cmd.readOnly = true;
+ cmd.isIncrementalSearchCommand = true;
+ cmd.scrollIntoView = "animate-cursor";
+ return cmd;
+});
+
+function IncrementalSearchKeyboardHandler(iSearch) {
+ this.$iSearch = iSearch;
+}
+
+oop.inherits(IncrementalSearchKeyboardHandler, HashHandler);
+
+(function() {
+
+ this.attach = function(editor) {
+ var iSearch = this.$iSearch;
+ HashHandler.call(this, exports.iSearchCommands, editor.commands.platform);
+ this.$commandExecHandler = editor.commands.addEventListener('exec', function(e) {
+ if (!e.command.isIncrementalSearchCommand)
+ return iSearch.deactivate();
+ e.stopPropagation();
+ e.preventDefault();
+ var scrollTop = editor.session.getScrollTop();
+ var result = e.command.exec(iSearch, e.args || {});
+ editor.renderer.scrollCursorIntoView(null, 0.5);
+ editor.renderer.animateScrolling(scrollTop);
+ return result;
+ });
+ };
+
+ this.detach = function(editor) {
+ if (!this.$commandExecHandler) return;
+ editor.commands.removeEventListener('exec', this.$commandExecHandler);
+ delete this.$commandExecHandler;
+ };
+
+ var handleKeyboard$super = this.handleKeyboard;
+ this.handleKeyboard = function(data, hashId, key, keyCode) {
+ if (((hashId === 1/*ctrl*/ || hashId === 8/*command*/) && key === 'v')
+ || (hashId === 1/*ctrl*/ && key === 'y')) return null;
+ var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode);
+ if (cmd.command) { return cmd; }
+ if (hashId == -1) {
+ var extendCmd = this.commands.extendSearchTerm;
+ if (extendCmd) { return {command: extendCmd, args: key}; }
+ }
+ return false;
+ };
+
+}).call(IncrementalSearchKeyboardHandler.prototype);
+
+
+exports.IncrementalSearchKeyboardHandler = IncrementalSearchKeyboardHandler;
+
+});
+
+define("ace/incremental_search",["require","exports","module","ace/lib/oop","ace/range","ace/search","ace/search_highlight","ace/commands/incremental_search_commands","ace/lib/dom","ace/commands/command_manager","ace/editor","ace/config"], function(require, exports, module) {
+"use strict";
+
+var oop = require("./lib/oop");
+var Range = require("./range").Range;
+var Search = require("./search").Search;
+var SearchHighlight = require("./search_highlight").SearchHighlight;
+var iSearchCommandModule = require("./commands/incremental_search_commands");
+var ISearchKbd = iSearchCommandModule.IncrementalSearchKeyboardHandler;
+function IncrementalSearch() {
+ this.$options = {wrap: false, skipCurrent: false};
+ this.$keyboardHandler = new ISearchKbd(this);
+}
+
+oop.inherits(IncrementalSearch, Search);
+
+function isRegExp(obj) {
+ return obj instanceof RegExp;
+}
+
+function regExpToObject(re) {
+ var string = String(re),
+ start = string.indexOf('/'),
+ flagStart = string.lastIndexOf('/');
+ return {
+ expression: string.slice(start+1, flagStart),
+ flags: string.slice(flagStart+1)
+ };
+}
+
+function stringToRegExp(string, flags) {
+ try {
+ return new RegExp(string, flags);
+ } catch (e) { return string; }
+}
+
+function objectToRegExp(obj) {
+ return stringToRegExp(obj.expression, obj.flags);
+}
+
+(function() {
+
+ this.activate = function(ed, backwards) {
+ this.$editor = ed;
+ this.$startPos = this.$currentPos = ed.getCursorPosition();
+ this.$options.needle = '';
+ this.$options.backwards = backwards;
+ ed.keyBinding.addKeyboardHandler(this.$keyboardHandler);
+ this.$originalEditorOnPaste = ed.onPaste; ed.onPaste = this.onPaste.bind(this);
+ this.$mousedownHandler = ed.addEventListener('mousedown', this.onMouseDown.bind(this));
+ this.selectionFix(ed);
+ this.statusMessage(true);
+ };
+
+ this.deactivate = function(reset) {
+ this.cancelSearch(reset);
+ var ed = this.$editor;
+ ed.keyBinding.removeKeyboardHandler(this.$keyboardHandler);
+ if (this.$mousedownHandler) {
+ ed.removeEventListener('mousedown', this.$mousedownHandler);
+ delete this.$mousedownHandler;
+ }
+ ed.onPaste = this.$originalEditorOnPaste;
+ this.message('');
+ };
+
+ this.selectionFix = function(editor) {
+ if (editor.selection.isEmpty() && !editor.session.$emacsMark) {
+ editor.clearSelection();
+ }
+ };
+
+ this.highlight = function(regexp) {
+ var sess = this.$editor.session,
+ hl = sess.$isearchHighlight = sess.$isearchHighlight || sess.addDynamicMarker(
+ new SearchHighlight(null, "ace_isearch-result", "text"));
+ hl.setRegexp(regexp);
+ sess._emit("changeBackMarker"); // force highlight layer redraw
+ };
+
+ this.cancelSearch = function(reset) {
+ var e = this.$editor;
+ this.$prevNeedle = this.$options.needle;
+ this.$options.needle = '';
+ if (reset) {
+ e.moveCursorToPosition(this.$startPos);
+ this.$currentPos = this.$startPos;
+ } else {
+ e.pushEmacsMark && e.pushEmacsMark(this.$startPos, false);
+ }
+ this.highlight(null);
+ return Range.fromPoints(this.$currentPos, this.$currentPos);
+ };
+
+ this.highlightAndFindWithNeedle = function(moveToNext, needleUpdateFunc) {
+ if (!this.$editor) return null;
+ var options = this.$options;
+ if (needleUpdateFunc) {
+ options.needle = needleUpdateFunc.call(this, options.needle || '') || '';
+ }
+ if (options.needle.length === 0) {
+ this.statusMessage(true);
+ return this.cancelSearch(true);
+ }
+ options.start = this.$currentPos;
+ var session = this.$editor.session,
+ found = this.find(session),
+ shouldSelect = this.$editor.emacsMark ?
+ !!this.$editor.emacsMark() : !this.$editor.selection.isEmpty();
+ if (found) {
+ if (options.backwards) found = Range.fromPoints(found.end, found.start);
+ this.$editor.selection.setRange(Range.fromPoints(shouldSelect ? this.$startPos : found.end, found.end));
+ if (moveToNext) this.$currentPos = found.end;
+ this.highlight(options.re);
+ }
+
+ this.statusMessage(found);
+
+ return found;
+ };
+
+ this.addString = function(s) {
+ return this.highlightAndFindWithNeedle(false, function(needle) {
+ if (!isRegExp(needle))
+ return needle + s;
+ var reObj = regExpToObject(needle);
+ reObj.expression += s;
+ return objectToRegExp(reObj);
+ });
+ };
+
+ this.removeChar = function(c) {
+ return this.highlightAndFindWithNeedle(false, function(needle) {
+ if (!isRegExp(needle))
+ return needle.substring(0, needle.length-1);
+ var reObj = regExpToObject(needle);
+ reObj.expression = reObj.expression.substring(0, reObj.expression.length-1);
+ return objectToRegExp(reObj);
+ });
+ };
+
+ this.next = function(options) {
+ options = options || {};
+ this.$options.backwards = !!options.backwards;
+ this.$currentPos = this.$editor.getCursorPosition();
+ return this.highlightAndFindWithNeedle(true, function(needle) {
+ return options.useCurrentOrPrevSearch && needle.length === 0 ?
+ this.$prevNeedle || '' : needle;
+ });
+ };
+
+ this.onMouseDown = function(evt) {
+ this.deactivate();
+ return true;
+ };
+
+ this.onPaste = function(text) {
+ this.addString(text);
+ };
+
+ this.convertNeedleToRegExp = function() {
+ return this.highlightAndFindWithNeedle(false, function(needle) {
+ return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig');
+ });
+ };
+
+ this.convertNeedleToString = function() {
+ return this.highlightAndFindWithNeedle(false, function(needle) {
+ return isRegExp(needle) ? regExpToObject(needle).expression : needle;
+ });
+ };
+
+ this.statusMessage = function(found) {
+ var options = this.$options, msg = '';
+ msg += options.backwards ? 'reverse-' : '';
+ msg += 'isearch: ' + options.needle;
+ msg += found ? '' : ' (not found)';
+ this.message(msg);
+ };
+
+ this.message = function(msg) {
+ if (this.$editor.showCommandLine) {
+ this.$editor.showCommandLine(msg);
+ this.$editor.focus();
+ }
+ };
+
+}).call(IncrementalSearch.prototype);
+
+
+exports.IncrementalSearch = IncrementalSearch;
+
+var dom = require('./lib/dom');
+dom.importCssString && dom.importCssString("\
+.ace_marker-layer .ace_isearch-result {\
+ position: absolute;\
+ z-index: 6;\
+ box-sizing: border-box;\
+}\
+div.ace_isearch-result {\
+ border-radius: 4px;\
+ background-color: rgba(255, 200, 0, 0.5);\
+ box-shadow: 0 0 4px rgb(255, 200, 0);\
+}\
+.ace_dark div.ace_isearch-result {\
+ background-color: rgb(100, 110, 160);\
+ box-shadow: 0 0 4px rgb(80, 90, 140);\
+}", "incremental-search-highlighting");
+var commands = require("./commands/command_manager");
+(function() {
+ this.setupIncrementalSearch = function(editor, val) {
+ if (this.usesIncrementalSearch == val) return;
+ this.usesIncrementalSearch = val;
+ var iSearchCommands = iSearchCommandModule.iSearchStartCommands;
+ var method = val ? 'addCommands' : 'removeCommands';
+ this[method](iSearchCommands);
+ };
+}).call(commands.CommandManager.prototype);
+var Editor = require("./editor").Editor;
+require("./config").defineOptions(Editor.prototype, "editor", {
+ useIncrementalSearch: {
+ set: function(val) {
+ this.keyBinding.$handlers.forEach(function(handler) {
+ if (handler.setupIncrementalSearch) {
+ handler.setupIncrementalSearch(this, val);
+ }
+ });
+ this._emit('incrementalSearchSettingChanged', {isEnabled: val});
+ }
+ }
+});
+
+});
+
+define("kitchen-sink/token_tooltip",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/range","ace/tooltip"], function(require, exports, module) {
+"use strict";
+
+var dom = require("ace/lib/dom");
+var oop = require("ace/lib/oop");
+var event = require("ace/lib/event");
+var Range = require("ace/range").Range;
+var Tooltip = require("ace/tooltip").Tooltip;
+
+function TokenTooltip (editor) {
+ if (editor.tokenTooltip)
+ return;
+ Tooltip.call(this, editor.container);
+ editor.tokenTooltip = this;
+ this.editor = editor;
+
+ this.update = this.update.bind(this);
+ this.onMouseMove = this.onMouseMove.bind(this);
+ this.onMouseOut = this.onMouseOut.bind(this);
+ event.addListener(editor.renderer.scroller, "mousemove", this.onMouseMove);
+ event.addListener(editor.renderer.content, "mouseout", this.onMouseOut);
+}
+
+oop.inherits(TokenTooltip, Tooltip);
+
+(function(){
+ this.token = {};
+ this.range = new Range();
+
+ this.update = function() {
+ this.$timer = null;
+
+ var r = this.editor.renderer;
+ if (this.lastT - (r.timeStamp || 0) > 1000) {
+ r.rect = null;
+ r.timeStamp = this.lastT;
+ this.maxHeight = window.innerHeight;
+ this.maxWidth = window.innerWidth;
+ }
+
+ var canvasPos = r.rect || (r.rect = r.scroller.getBoundingClientRect());
+ var offset = (this.x + r.scrollLeft - canvasPos.left - r.$padding) / r.characterWidth;
+ var row = Math.floor((this.y + r.scrollTop - canvasPos.top) / r.lineHeight);
+ var col = Math.round(offset);
+
+ var screenPos = {row: row, column: col, side: offset - col > 0 ? 1 : -1};
+ var session = this.editor.session;
+ var docPos = session.screenToDocumentPosition(screenPos.row, screenPos.column);
+ var token = session.getTokenAt(docPos.row, docPos.column);
+
+ if (!token && !session.getLine(docPos.row)) {
+ token = {
+ type: "",
+ value: "",
+ state: session.bgTokenizer.getState(0)
+ };
+ }
+ if (!token) {
+ session.removeMarker(this.marker);
+ this.hide();
+ return;
+ }
+
+ var tokenText = token.type;
+ if (token.state)
+ tokenText += "|" + token.state;
+ if (token.merge)
+ tokenText += "\n merge";
+ if (token.stateTransitions)
+ tokenText += "\n " + token.stateTransitions.join("\n ");
+
+ if (this.tokenText != tokenText) {
+ this.setText(tokenText);
+ this.width = this.getWidth();
+ this.height = this.getHeight();
+ this.tokenText = tokenText;
+ }
+
+ this.show(null, this.x, this.y);
+
+ this.token = token;
+ session.removeMarker(this.marker);
+ this.range = new Range(docPos.row, token.start, docPos.row, token.start + token.value.length);
+ this.marker = session.addMarker(this.range, "ace_bracket", "text");
+ };
+
+ this.onMouseMove = function(e) {
+ this.x = e.clientX;
+ this.y = e.clientY;
+ if (this.isOpen) {
+ this.lastT = e.timeStamp;
+ this.setPosition(this.x, this.y);
+ }
+ if (!this.$timer)
+ this.$timer = setTimeout(this.update, 100);
+ };
+
+ this.onMouseOut = function(e) {
+ if (e && e.currentTarget.contains(e.relatedTarget))
+ return;
+ this.hide();
+ this.editor.session.removeMarker(this.marker);
+ this.$timer = clearTimeout(this.$timer);
+ };
+
+ this.setPosition = function(x, y) {
+ if (x + 10 + this.width > this.maxWidth)
+ x = window.innerWidth - this.width - 10;
+ if (y > window.innerHeight * 0.75 || y + 20 + this.height > this.maxHeight)
+ y = y - this.height - 30;
+
+ Tooltip.prototype.setPosition.call(this, x + 10, y + 20);
+ };
+
+ this.destroy = function() {
+ this.onMouseOut();
+ event.removeListener(this.editor.renderer.scroller, "mousemove", this.onMouseMove);
+ event.removeListener(this.editor.renderer.content, "mouseout", this.onMouseOut);
+ delete this.editor.tokenTooltip;
+ };
+
+}).call(TokenTooltip.prototype);
+
+exports.TokenTooltip = TokenTooltip;
+
+});
+
+define("ace/split",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/editor","ace/virtual_renderer","ace/edit_session"], function(require, exports, module) {
+"use strict";
+
+var oop = require("./lib/oop");
+var lang = require("./lib/lang");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+
+var Editor = require("./editor").Editor;
+var Renderer = require("./virtual_renderer").VirtualRenderer;
+var EditSession = require("./edit_session").EditSession;
+
+
+var Split = function(container, theme, splits) {
+ this.BELOW = 1;
+ this.BESIDE = 0;
+
+ this.$container = container;
+ this.$theme = theme;
+ this.$splits = 0;
+ this.$editorCSS = "";
+ this.$editors = [];
+ this.$orientation = this.BESIDE;
+
+ this.setSplits(splits || 1);
+ this.$cEditor = this.$editors[0];
+
+
+ this.on("focus", function(editor) {
+ this.$cEditor = editor;
+ }.bind(this));
+};
+
+(function(){
+
+ oop.implement(this, EventEmitter);
+
+ this.$createEditor = function() {
+ var el = document.createElement("div");
+ el.className = this.$editorCSS;
+ el.style.cssText = "position: absolute; top:0px; bottom:0px";
+ this.$container.appendChild(el);
+ var editor = new Editor(new Renderer(el, this.$theme));
+
+ editor.on("focus", function() {
+ this._emit("focus", editor);
+ }.bind(this));
+
+ this.$editors.push(editor);
+ editor.setFontSize(this.$fontSize);
+ return editor;
+ };
+
+ this.setSplits = function(splits) {
+ var editor;
+ if (splits < 1) {
+ throw "The number of splits have to be > 0!";
+ }
+
+ if (splits == this.$splits) {
+ return;
+ } else if (splits > this.$splits) {
+ while (this.$splits < this.$editors.length && this.$splits < splits) {
+ editor = this.$editors[this.$splits];
+ this.$container.appendChild(editor.container);
+ editor.setFontSize(this.$fontSize);
+ this.$splits ++;
+ }
+ while (this.$splits < splits) {
+ this.$createEditor();
+ this.$splits ++;
+ }
+ } else {
+ while (this.$splits > splits) {
+ editor = this.$editors[this.$splits - 1];
+ this.$container.removeChild(editor.container);
+ this.$splits --;
+ }
+ }
+ this.resize();
+ };
+ this.getSplits = function() {
+ return this.$splits;
+ };
+ this.getEditor = function(idx) {
+ return this.$editors[idx];
+ };
+ this.getCurrentEditor = function() {
+ return this.$cEditor;
+ };
+ this.focus = function() {
+ this.$cEditor.focus();
+ };
+ this.blur = function() {
+ this.$cEditor.blur();
+ };
+ this.setTheme = function(theme) {
+ this.$editors.forEach(function(editor) {
+ editor.setTheme(theme);
+ });
+ };
+ this.setKeyboardHandler = function(keybinding) {
+ this.$editors.forEach(function(editor) {
+ editor.setKeyboardHandler(keybinding);
+ });
+ };
+ this.forEach = function(callback, scope) {
+ this.$editors.forEach(callback, scope);
+ };
+
+
+ this.$fontSize = "";
+ this.setFontSize = function(size) {
+ this.$fontSize = size;
+ this.forEach(function(editor) {
+ editor.setFontSize(size);
+ });
+ };
+
+ this.$cloneSession = function(session) {
+ var s = new EditSession(session.getDocument(), session.getMode());
+
+ var undoManager = session.getUndoManager();
+ s.setUndoManager(undoManager);
+ s.setTabSize(session.getTabSize());
+ s.setUseSoftTabs(session.getUseSoftTabs());
+ s.setOverwrite(session.getOverwrite());
+ s.setBreakpoints(session.getBreakpoints());
+ s.setUseWrapMode(session.getUseWrapMode());
+ s.setUseWorker(session.getUseWorker());
+ s.setWrapLimitRange(session.$wrapLimitRange.min,
+ session.$wrapLimitRange.max);
+ s.$foldData = session.$cloneFoldData();
+
+ return s;
+ };
+ this.setSession = function(session, idx) {
+ var editor;
+ if (idx == null) {
+ editor = this.$cEditor;
+ } else {
+ editor = this.$editors[idx];
+ }
+ var isUsed = this.$editors.some(function(editor) {
+ return editor.session === session;
+ });
+
+ if (isUsed) {
+ session = this.$cloneSession(session);
+ }
+ editor.setSession(session);
+ return session;
+ };
+ this.getOrientation = function() {
+ return this.$orientation;
+ };
+ this.setOrientation = function(orientation) {
+ if (this.$orientation == orientation) {
+ return;
+ }
+ this.$orientation = orientation;
+ this.resize();
+ };
+ this.resize = function() {
+ var width = this.$container.clientWidth;
+ var height = this.$container.clientHeight;
+ var editor;
+
+ if (this.$orientation == this.BESIDE) {
+ var editorWidth = width / this.$splits;
+ for (var i = 0; i < this.$splits; i++) {
+ editor = this.$editors[i];
+ editor.container.style.width = editorWidth + "px";
+ editor.container.style.top = "0px";
+ editor.container.style.left = i * editorWidth + "px";
+ editor.container.style.height = height + "px";
+ editor.resize();
+ }
+ } else {
+ var editorHeight = height / this.$splits;
+ for (var i = 0; i < this.$splits; i++) {
+ editor = this.$editors[i];
+ editor.container.style.width = width + "px";
+ editor.container.style.top = i * editorHeight + "px";
+ editor.container.style.left = "0px";
+ editor.container.style.height = editorHeight + "px";
+ editor.resize();
+ }
+ }
+ };
+
+}).call(Split.prototype);
+
+exports.Split = Split;
+});
+
+define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
+'use strict';
+var dom = require("../../lib/dom");
+var cssText = "#ace_settingsmenu, #kbshortcutmenu {\
+background-color: #F7F7F7;\
+color: black;\
+box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);\
+padding: 1em 0.5em 2em 1em;\
+overflow: auto;\
+position: absolute;\
+margin: 0;\
+bottom: 0;\
+right: 0;\
+top: 0;\
+z-index: 9991;\
+cursor: default;\
+}\
+.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {\
+box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);\
+background-color: rgba(255, 255, 255, 0.6);\
+color: black;\
+}\
+.ace_optionsMenuEntry:hover {\
+background-color: rgba(100, 100, 100, 0.1);\
+transition: all 0.3s\
+}\
+.ace_closeButton {\
+background: rgba(245, 146, 146, 0.5);\
+border: 1px solid #F48A8A;\
+border-radius: 50%;\
+padding: 7px;\
+position: absolute;\
+right: -8px;\
+top: -8px;\
+z-index: 100000;\
+}\
+.ace_closeButton{\
+background: rgba(245, 146, 146, 0.9);\
+}\
+.ace_optionsMenuKey {\
+color: darkslateblue;\
+font-weight: bold;\
+}\
+.ace_optionsMenuCommand {\
+color: darkcyan;\
+font-weight: normal;\
+}\
+.ace_optionsMenuEntry input, .ace_optionsMenuEntry button {\
+vertical-align: middle;\
+}\
+.ace_optionsMenuEntry button[ace_selected_button=true] {\
+background: #e7e7e7;\
+box-shadow: 1px 0px 2px 0px #adadad inset;\
+border-color: #adadad;\
+}\
+.ace_optionsMenuEntry button {\
+background: white;\
+border: 1px solid lightgray;\
+margin: 0px;\
+}\
+.ace_optionsMenuEntry button:hover{\
+background: #f0f0f0;\
+}";
+dom.importCssString(cssText);
+
+module.exports.overlayPage = function overlayPage(editor, contentElement, callback) {
+ var closer = document.createElement('div');
+ var ignoreFocusOut = false;
+
+ function documentEscListener(e) {
+ if (e.keyCode === 27) {
+ close();
+ }
+ }
+
+ function close() {
+ if (!closer) return;
+ document.removeEventListener('keydown', documentEscListener);
+ closer.parentNode.removeChild(closer);
+ if (editor) {
+ editor.focus();
+ }
+ closer = null;
+ callback && callback();
+ }
+ function setIgnoreFocusOut(ignore) {
+ ignoreFocusOut = ignore;
+ if (ignore) {
+ closer.style.pointerEvents = "none";
+ contentElement.style.pointerEvents = "auto";
+ }
+ }
+
+ closer.style.cssText = 'margin: 0; padding: 0; ' +
+ 'position: fixed; top:0; bottom:0; left:0; right:0;' +
+ 'z-index: 9990; ' +
+ (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');
+ closer.addEventListener('click', function(e) {
+ if (!ignoreFocusOut) {
+ close();
+ }
+ });
+ document.addEventListener('keydown', documentEscListener);
+
+ contentElement.addEventListener('click', function (e) {
+ e.stopPropagation();
+ });
+
+ closer.appendChild(contentElement);
+ document.body.appendChild(closer);
+ if (editor) {
+ editor.blur();
+ }
+ return {
+ close: close,
+ setIgnoreFocusOut: setIgnoreFocusOut
+ };
+};
+
+});
+
+define("ace/ext/themelist",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+var themeData = [
+ ["Chrome" ],
+ ["Clouds" ],
+ ["Crimson Editor" ],
+ ["Dawn" ],
+ ["Dreamweaver" ],
+ ["Eclipse" ],
+ ["GitHub" ],
+ ["IPlastic" ],
+ ["Solarized Light"],
+ ["TextMate" ],
+ ["Tomorrow" ],
+ ["XCode" ],
+ ["Kuroir"],
+ ["KatzenMilch"],
+ ["SQL Server" ,"sqlserver" , "light"],
+ ["Ambiance" ,"ambiance" , "dark"],
+ ["Chaos" ,"chaos" , "dark"],
+ ["Clouds Midnight" ,"clouds_midnight" , "dark"],
+ ["Dracula" ,"" , "dark"],
+ ["Cobalt" ,"cobalt" , "dark"],
+ ["Gruvbox" ,"gruvbox" , "dark"],
+ ["Green on Black" ,"gob" , "dark"],
+ ["idle Fingers" ,"idle_fingers" , "dark"],
+ ["krTheme" ,"kr_theme" , "dark"],
+ ["Merbivore" ,"merbivore" , "dark"],
+ ["Merbivore Soft" ,"merbivore_soft" , "dark"],
+ ["Mono Industrial" ,"mono_industrial" , "dark"],
+ ["Monokai" ,"monokai" , "dark"],
+ ["Pastel on dark" ,"pastel_on_dark" , "dark"],
+ ["Solarized Dark" ,"solarized_dark" , "dark"],
+ ["Terminal" ,"terminal" , "dark"],
+ ["Tomorrow Night" ,"tomorrow_night" , "dark"],
+ ["Tomorrow Night Blue" ,"tomorrow_night_blue" , "dark"],
+ ["Tomorrow Night Bright","tomorrow_night_bright" , "dark"],
+ ["Tomorrow Night 80s" ,"tomorrow_night_eighties" , "dark"],
+ ["Twilight" ,"twilight" , "dark"],
+ ["Vibrant Ink" ,"vibrant_ink" , "dark"]
+];
+
+
+exports.themesByName = {};
+exports.themes = themeData.map(function(data) {
+ var name = data[1] || data[0].replace(/ /g, "_").toLowerCase();
+ var theme = {
+ caption: data[0],
+ theme: "ace/theme/" + name,
+ isDark: data[2] == "dark",
+ name: name
+ };
+ exports.themesByName[name] = theme;
+ return theme;
+});
+
+});
+
+define("ace/ext/options",["require","exports","module","ace/ext/menu_tools/overlay_page","ace/lib/dom","ace/lib/oop","ace/config","ace/lib/event_emitter","ace/ext/modelist","ace/ext/themelist"], function(require, exports, module) {
+"use strict";
+
+require("./menu_tools/overlay_page");
+
+var dom = require("../lib/dom");
+var oop = require("../lib/oop");
+var config = require("../config");
+var EventEmitter = require("../lib/event_emitter").EventEmitter;
+var buildDom = dom.buildDom;
+
+var modelist = require("./modelist");
+var themelist = require("./themelist");
+
+var themes = { Bright: [], Dark: [] };
+themelist.themes.forEach(function(x) {
+ themes[x.isDark ? "Dark" : "Bright"].push({ caption: x.caption, value: x.theme });
+});
+
+var modes = modelist.modes.map(function(x){
+ return { caption: x.caption, value: x.mode };
+});
+
+
+var optionGroups = {
+ Main: {
+ Mode: {
+ path: "mode",
+ type: "select",
+ items: modes
+ },
+ Theme: {
+ path: "theme",
+ type: "select",
+ items: themes
+ },
+ "Keybinding": {
+ type: "buttonBar",
+ path: "keyboardHandler",
+ items: [
+ { caption : "Ace", value : null },
+ { caption : "Vim", value : "ace/keyboard/vim" },
+ { caption : "Emacs", value : "ace/keyboard/emacs" },
+ { caption : "Sublime", value : "ace/keyboard/sublime" },
+ { caption : "VSCode", value : "ace/keyboard/vscode" }
+ ]
+ },
+ "Font Size": {
+ path: "fontSize",
+ type: "number",
+ defaultValue: 12,
+ defaults: [
+ {caption: "12px", value: 12},
+ {caption: "24px", value: 24}
+ ]
+ },
+ "Soft Wrap": {
+ type: "buttonBar",
+ path: "wrap",
+ items: [
+ { caption : "Off", value : "off" },
+ { caption : "View", value : "free" },
+ { caption : "margin", value : "printMargin" },
+ { caption : "40", value : "40" }
+ ]
+ },
+ "Cursor Style": {
+ path: "cursorStyle",
+ items: [
+ { caption : "Ace", value : "ace" },
+ { caption : "Slim", value : "slim" },
+ { caption : "Smooth", value : "smooth" },
+ { caption : "Smooth And Slim", value : "smooth slim" },
+ { caption : "Wide", value : "wide" }
+ ]
+ },
+ "Folding": {
+ path: "foldStyle",
+ items: [
+ { caption : "Manual", value : "manual" },
+ { caption : "Mark begin", value : "markbegin" },
+ { caption : "Mark begin and end", value : "markbeginend" }
+ ]
+ },
+ "Soft Tabs": [{
+ path: "useSoftTabs"
+ }, {
+ path: "tabSize",
+ type: "number",
+ values: [2, 3, 4, 8, 16]
+ }],
+ "Overscroll": {
+ type: "buttonBar",
+ path: "scrollPastEnd",
+ items: [
+ { caption : "None", value : 0 },
+ { caption : "Half", value : 0.5 },
+ { caption : "Full", value : 1 }
+ ]
+ }
+ },
+ More: {
+ "Atomic soft tabs": {
+ path: "navigateWithinSoftTabs"
+ },
+ "Enable Behaviours": {
+ path: "behavioursEnabled"
+ },
+ "Full Line Selection": {
+ type: "checkbox",
+ values: "text|line",
+ path: "selectionStyle"
+ },
+ "Highlight Active Line": {
+ path: "highlightActiveLine"
+ },
+ "Show Invisibles": {
+ path: "showInvisibles"
+ },
+ "Show Indent Guides": {
+ path: "displayIndentGuides"
+ },
+ "Persistent Scrollbar": [{
+ path: "hScrollBarAlwaysVisible"
+ }, {
+ path: "vScrollBarAlwaysVisible"
+ }],
+ "Animate scrolling": {
+ path: "animatedScroll"
+ },
+ "Show Gutter": {
+ path: "showGutter"
+ },
+ "Show Line Numbers": {
+ path: "showLineNumbers"
+ },
+ "Relative Line Numbers": {
+ path: "relativeLineNumbers"
+ },
+ "Fixed Gutter Width": {
+ path: "fixedWidthGutter"
+ },
+ "Show Print Margin": [{
+ path: "showPrintMargin"
+ }, {
+ type: "number",
+ path: "printMarginColumn"
+ }],
+ "Indented Soft Wrap": {
+ path: "indentedSoftWrap"
+ },
+ "Highlight selected word": {
+ path: "highlightSelectedWord"
+ },
+ "Fade Fold Widgets": {
+ path: "fadeFoldWidgets"
+ },
+ "Use textarea for IME": {
+ path: "useTextareaForIME"
+ },
+ "Merge Undo Deltas": {
+ path: "mergeUndoDeltas",
+ items: [
+ { caption : "Always", value : "always" },
+ { caption : "Never", value : "false" },
+ { caption : "Timed", value : "true" }
+ ]
+ },
+ "Elastic Tabstops": {
+ path: "useElasticTabstops"
+ },
+ "Incremental Search": {
+ path: "useIncrementalSearch"
+ },
+ "Read-only": {
+ path: "readOnly"
+ },
+ "Copy without selection": {
+ path: "copyWithEmptySelection"
+ },
+ "Live Autocompletion": {
+ path: "enableLiveAutocompletion"
+ }
+ }
+};
+
+
+var OptionPanel = function(editor, element) {
+ this.editor = editor;
+ this.container = element || document.createElement("div");
+ this.groups = [];
+ this.options = {};
+};
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.add = function(config) {
+ if (config.Main)
+ oop.mixin(optionGroups.Main, config.Main);
+ if (config.More)
+ oop.mixin(optionGroups.More, config.More);
+ };
+
+ this.render = function() {
+ this.container.innerHTML = "";
+ buildDom(["table", {id: "controls"},
+ this.renderOptionGroup(optionGroups.Main),
+ ["tr", null, ["td", {colspan: 2},
+ ["table", {id: "more-controls"},
+ this.renderOptionGroup(optionGroups.More)
+ ]
+ ]],
+ ["tr", null, ["td", {colspan: 2}, "version " + config.version]]
+ ], this.container);
+ };
+
+ this.renderOptionGroup = function(group) {
+ return Object.keys(group).map(function(key, i) {
+ var item = group[key];
+ if (!item.position)
+ item.position = i / 10000;
+ if (!item.label)
+ item.label = key;
+ return item;
+ }).sort(function(a, b) {
+ return a.position - b.position;
+ }).map(function(item) {
+ return this.renderOption(item.label, item);
+ }, this);
+ };
+
+ this.renderOptionControl = function(key, option) {
+ var self = this;
+ if (Array.isArray(option)) {
+ return option.map(function(x) {
+ return self.renderOptionControl(key, x);
+ });
+ }
+ var control;
+
+ var value = self.getOption(option);
+
+ if (option.values && option.type != "checkbox") {
+ if (typeof option.values == "string")
+ option.values = option.values.split("|");
+ option.items = option.values.map(function(v) {
+ return { value: v, name: v };
+ });
+ }
+
+ if (option.type == "buttonBar") {
+ control = ["div", option.items.map(function(item) {
+ return ["button", {
+ value: item.value,
+ ace_selected_button: value == item.value,
+ onclick: function() {
+ self.setOption(option, item.value);
+ var nodes = this.parentNode.querySelectorAll("[ace_selected_button]");
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].removeAttribute("ace_selected_button");
+ }
+ this.setAttribute("ace_selected_button", true);
+ }
+ }, item.desc || item.caption || item.name];
+ })];
+ } else if (option.type == "number") {
+ control = ["input", {type: "number", value: value || option.defaultValue, style:"width:3em", oninput: function() {
+ self.setOption(option, parseInt(this.value));
+ }}];
+ if (option.defaults) {
+ control = [control, option.defaults.map(function(item) {
+ return ["button", {onclick: function() {
+ var input = this.parentNode.firstChild;
+ input.value = item.value;
+ input.oninput();
+ }}, item.caption];
+ })];
+ }
+ } else if (option.items) {
+ var buildItems = function(items) {
+ return items.map(function(item) {
+ return ["option", { value: item.value || item.name }, item.desc || item.caption || item.name];
+ });
+ };
+
+ var items = Array.isArray(option.items)
+ ? buildItems(option.items)
+ : Object.keys(option.items).map(function(key) {
+ return ["optgroup", {"label": key}, buildItems(option.items[key])];
+ });
+ control = ["select", { id: key, value: value, onchange: function() {
+ self.setOption(option, this.value);
+ } }, items];
+ } else {
+ if (typeof option.values == "string")
+ option.values = option.values.split("|");
+ if (option.values) value = value == option.values[1];
+ control = ["input", { type: "checkbox", id: key, checked: value || null, onchange: function() {
+ var value = this.checked;
+ if (option.values) value = option.values[value ? 1 : 0];
+ self.setOption(option, value);
+ }}];
+ if (option.type == "checkedNumber") {
+ control = [control, []];
+ }
+ }
+ return control;
+ };
+
+ this.renderOption = function(key, option) {
+ if (option.path && !option.onchange && !this.editor.$options[option.path])
+ return;
+ this.options[option.path] = option;
+ var safeKey = "-" + option.path;
+ var control = this.renderOptionControl(safeKey, option);
+ return ["tr", {class: "ace_optionsMenuEntry"}, ["td",
+ ["label", {for: safeKey}, key]
+ ], ["td", control]];
+ };
+
+ this.setOption = function(option, value) {
+ if (typeof option == "string")
+ option = this.options[option];
+ if (value == "false") value = false;
+ if (value == "true") value = true;
+ if (value == "null") value = null;
+ if (value == "undefined") value = undefined;
+ if (typeof value == "string" && parseFloat(value).toString() == value)
+ value = parseFloat(value);
+ if (option.onchange)
+ option.onchange(value);
+ else if (option.path)
+ this.editor.setOption(option.path, value);
+ this._signal("setOption", {name: option.path, value: value});
+ };
+
+ this.getOption = function(option) {
+ if (option.getValue)
+ return option.getValue();
+ return this.editor.getOption(option.path);
+ };
+
+}).call(OptionPanel.prototype);
+
+exports.OptionPanel = OptionPanel;
+
+});
+
+define("ace/ext/statusbar",["require","exports","module","ace/lib/dom","ace/lib/lang"], function(require, exports, module) {
+"use strict";
+var dom = require("../lib/dom");
+var lang = require("../lib/lang");
+
+var StatusBar = function(editor, parentNode) {
+ this.element = dom.createElement("div");
+ this.element.className = "ace_status-indicator";
+ this.element.style.cssText = "display: inline-block;";
+ parentNode.appendChild(this.element);
+
+ var statusUpdate = lang.delayedCall(function(){
+ this.updateStatus(editor);
+ }.bind(this)).schedule.bind(null, 100);
+
+ editor.on("changeStatus", statusUpdate);
+ editor.on("changeSelection", statusUpdate);
+ editor.on("keyboardActivity", statusUpdate);
+};
+
+(function(){
+ this.updateStatus = function(editor) {
+ var status = [];
+ function add(str, separator) {
+ str && status.push(str, separator || "|");
+ }
+
+ add(editor.keyBinding.getStatusText(editor));
+ if (editor.commands.recording)
+ add("REC");
+
+ var sel = editor.selection;
+ var c = sel.lead;
+
+ if (!sel.isEmpty()) {
+ var r = editor.getSelectionRange();
+ add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")", " ");
+ }
+ add(c.row + ":" + c.column, " ");
+ if (sel.rangeCount)
+ add("[" + sel.rangeCount + "]", " ");
+ status.pop();
+ this.element.textContent = status.join("");
+ };
+}).call(StatusBar.prototype);
+
+exports.StatusBar = StatusBar;
+
+});
+
+define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/lib/dom","ace/editor"], function(require, exports, module) {
+"use strict";
+var oop = require("./lib/oop");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+var lang = require("./lib/lang");
+var Range = require("./range").Range;
+var RangeList = require("./range_list").RangeList;
+var HashHandler = require("./keyboard/hash_handler").HashHandler;
+var Tokenizer = require("./tokenizer").Tokenizer;
+var clipboard = require("./clipboard");
+
+var VARIABLES = {
+ CURRENT_WORD: function(editor) {
+ return editor.session.getTextRange(editor.session.getWordRange());
+ },
+ SELECTION: function(editor, name, indentation) {
+ var text = editor.session.getTextRange();
+ if (indentation)
+ return text.replace(/\n\r?([ \t]*\S)/g, "\n" + indentation + "$1");
+ return text;
+ },
+ CURRENT_LINE: function(editor) {
+ return editor.session.getLine(editor.getCursorPosition().row);
+ },
+ PREV_LINE: function(editor) {
+ return editor.session.getLine(editor.getCursorPosition().row - 1);
+ },
+ LINE_INDEX: function(editor) {
+ return editor.getCursorPosition().row;
+ },
+ LINE_NUMBER: function(editor) {
+ return editor.getCursorPosition().row + 1;
+ },
+ SOFT_TABS: function(editor) {
+ return editor.session.getUseSoftTabs() ? "YES" : "NO";
+ },
+ TAB_SIZE: function(editor) {
+ return editor.session.getTabSize();
+ },
+ CLIPBOARD: function(editor) {
+ return clipboard.getText && clipboard.getText();
+ },
+ FILENAME: function(editor) {
+ return /[^/\\]*$/.exec(this.FILEPATH(editor))[0];
+ },
+ FILENAME_BASE: function(editor) {
+ return /[^/\\]*$/.exec(this.FILEPATH(editor))[0].replace(/\.[^.]*$/, "");
+ },
+ DIRECTORY: function(editor) {
+ return this.FILEPATH(editor).replace(/[^/\\]*$/, "");
+ },
+ FILEPATH: function(editor) { return "/not implemented.txt"; },
+ WORKSPACE_NAME: function() { return "Unknown"; },
+ FULLNAME: function() { return "Unknown"; },
+ BLOCK_COMMENT_START: function(editor) {
+ var mode = editor.session.$mode || {};
+ return mode.blockComment && mode.blockComment.start || "";
+ },
+ BLOCK_COMMENT_END: function(editor) {
+ var mode = editor.session.$mode || {};
+ return mode.blockComment && mode.blockComment.end || "";
+ },
+ LINE_COMMENT: function(editor) {
+ var mode = editor.session.$mode || {};
+ return mode.lineCommentStart || "";
+ },
+ CURRENT_YEAR: date.bind(null, {year: "numeric"}),
+ CURRENT_YEAR_SHORT: date.bind(null, {year: "2-digit"}),
+ CURRENT_MONTH: date.bind(null, {month: "numeric"}),
+ CURRENT_MONTH_NAME: date.bind(null, {month: "long"}),
+ CURRENT_MONTH_NAME_SHORT: date.bind(null, {month: "short"}),
+ CURRENT_DATE: date.bind(null, {day: "2-digit"}),
+ CURRENT_DAY_NAME: date.bind(null, {weekday: "long"}),
+ CURRENT_DAY_NAME_SHORT: date.bind(null, {weekday: "short"}),
+ CURRENT_HOUR: date.bind(null, {hour: "2-digit", hour12: false}),
+ CURRENT_MINUTE: date.bind(null, {minute: "2-digit"}),
+ CURRENT_SECOND: date.bind(null, {second: "2-digit"})
+};
+
+VARIABLES.SELECTED_TEXT = VARIABLES.SELECTION;
+
+function date(dateFormat) {
+ var str = new Date().toLocaleString("en-us", dateFormat);
+ return str.length == 1 ? "0" + str : str;
+}
+
+var SnippetManager = function() {
+ this.snippetMap = {};
+ this.snippetNameMap = {};
+};
+
+(function() {
+ oop.implement(this, EventEmitter);
+
+ this.getTokenizer = function() {
+ return SnippetManager.$tokenizer || this.createTokenizer();
+ };
+
+ this.createTokenizer = function() {
+ function TabstopToken(str) {
+ str = str.substr(1);
+ if (/^\d+$/.test(str))
+ return [{tabstopId: parseInt(str, 10)}];
+ return [{text: str}];
+ }
+ function escape(ch) {
+ return "(?:[^\\\\" + ch + "]|\\\\.)";
+ }
+ var formatMatcher = {
+ regex: "/(" + escape("/") + "+)/",
+ onMatch: function(val, state, stack) {
+ var ts = stack[0];
+ ts.fmtString = true;
+ ts.guard = val.slice(1, -1);
+ ts.flag = "";
+ return "";
+ },
+ next: "formatString"
+ };
+
+ SnippetManager.$tokenizer = new Tokenizer({
+ start: [
+ {regex: /\\./, onMatch: function(val, state, stack) {
+ var ch = val[1];
+ if (ch == "}" && stack.length) {
+ val = ch;
+ } else if ("`$\\".indexOf(ch) != -1) {
+ val = ch;
+ }
+ return [val];
+ }},
+ {regex: /}/, onMatch: function(val, state, stack) {
+ return [stack.length ? stack.shift() : val];
+ }},
+ {regex: /\$(?:\d+|\w+)/, onMatch: TabstopToken},
+ {regex: /\$\{[\dA-Z_a-z]+/, onMatch: function(str, state, stack) {
+ var t = TabstopToken(str.substr(1));
+ stack.unshift(t[0]);
+ return t;
+ }, next: "snippetVar"},
+ {regex: /\n/, token: "newline", merge: false}
+ ],
+ snippetVar: [
+ {regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) {
+ var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function(operator) {
+ return operator.length == 2 ? operator[1] : "\x00";
+ }).split("\x00");
+ stack[0].choices = choices;
+ return [choices[0]];
+ }, next: "start"},
+ formatMatcher,
+ {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "start"}
+ ],
+ formatString: [
+ {regex: /:/, onMatch: function(val, state, stack) {
+ if (stack.length && stack[0].expectElse) {
+ stack[0].expectElse = false;
+ stack[0].ifEnd = {elseEnd: stack[0]};
+ return [stack[0].ifEnd];
+ }
+ return ":";
+ }},
+ {regex: /\\./, onMatch: function(val, state, stack) {
+ var ch = val[1];
+ if (ch == "}" && stack.length)
+ val = ch;
+ else if ("`$\\".indexOf(ch) != -1)
+ val = ch;
+ else if (ch == "n")
+ val = "\n";
+ else if (ch == "t")
+ val = "\t";
+ else if ("ulULE".indexOf(ch) != -1)
+ val = {changeCase: ch, local: ch > "a"};
+ return [val];
+ }},
+ {regex: "/\\w*}", onMatch: function(val, state, stack) {
+ var next = stack.shift();
+ if (next)
+ next.flag = val.slice(1, -1);
+ this.next = next && next.tabstopId ? "start" : "";
+ return [next || val];
+ }, next: "start"},
+ {regex: /\$(?:\d+|\w+)/, onMatch: function(val, state, stack) {
+ return [{text: val.slice(1)}];
+ }},
+ {regex: /\${\w+/, onMatch: function(val, state, stack) {
+ var token = {text: val.slice(2)};
+ stack.unshift(token);
+ return [token];
+ }, next: "formatStringVar"},
+ {regex: /\n/, token: "newline", merge: false},
+ {regex: /}/, onMatch: function(val, state, stack) {
+ var next = stack.shift();
+ this.next = next && next.tabstopId ? "start" : "";
+ return [next || val];
+ }, next: "start"}
+ ],
+ formatStringVar: [
+ {regex: /:\/\w+}/, onMatch: function(val, state, stack) {
+ var ts = stack[0];
+ ts.formatFunction = val.slice(2, -1);
+ return [stack.shift()];
+ }, next: "formatString"},
+ formatMatcher,
+ {regex: /:[\?\-+]?/, onMatch: function(val, state, stack) {
+ if (val[1] == "+")
+ stack[0].ifEnd = stack[0];
+ if (val[1] == "?")
+ stack[0].expectElse = true;
+ }, next: "formatString"},
+ {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "formatString"}
+ ]
+ });
+ return SnippetManager.$tokenizer;
+ };
+
+ this.tokenizeTmSnippet = function(str, startState) {
+ return this.getTokenizer().getLineTokens(str, startState).tokens.map(function(x) {
+ return x.value || x;
+ });
+ };
+
+ this.getVariableValue = function(editor, name, indentation) {
+ if (/^\d+$/.test(name))
+ return (this.variables.__ || {})[name] || "";
+ if (/^[A-Z]\d+$/.test(name))
+ return (this.variables[name[0] + "__"] || {})[name.substr(1)] || "";
+
+ name = name.replace(/^TM_/, "");
+ if (!this.variables.hasOwnProperty(name))
+ return "";
+ var value = this.variables[name];
+ if (typeof value == "function")
+ value = this.variables[name](editor, name, indentation);
+ return value == null ? "" : value;
+ };
+
+ this.variables = VARIABLES;
+ this.tmStrFormat = function(str, ch, editor) {
+ if (!ch.fmt) return str;
+ var flag = ch.flag || "";
+ var re = ch.guard;
+ re = new RegExp(re, flag.replace(/[^gim]/g, ""));
+ var fmtTokens = typeof ch.fmt == "string" ? this.tokenizeTmSnippet(ch.fmt, "formatString") : ch.fmt;
+ var _self = this;
+ var formatted = str.replace(re, function() {
+ var oldArgs = _self.variables.__;
+ _self.variables.__ = [].slice.call(arguments);
+ var fmtParts = _self.resolveVariables(fmtTokens, editor);
+ var gChangeCase = "E";
+ for (var i = 0; i < fmtParts.length; i++) {
+ var ch = fmtParts[i];
+ if (typeof ch == "object") {
+ fmtParts[i] = "";
+ if (ch.changeCase && ch.local) {
+ var next = fmtParts[i + 1];
+ if (next && typeof next == "string") {
+ if (ch.changeCase == "u")
+ fmtParts[i] = next[0].toUpperCase();
+ else
+ fmtParts[i] = next[0].toLowerCase();
+ fmtParts[i + 1] = next.substr(1);
+ }
+ } else if (ch.changeCase) {
+ gChangeCase = ch.changeCase;
+ }
+ } else if (gChangeCase == "U") {
+ fmtParts[i] = ch.toUpperCase();
+ } else if (gChangeCase == "L") {
+ fmtParts[i] = ch.toLowerCase();
+ }
+ }
+ _self.variables.__ = oldArgs;
+ return fmtParts.join("");
+ });
+ return formatted;
+ };
+
+ this.tmFormatFunction = function(str, ch, editor) {
+ if (ch.formatFunction == "upcase")
+ return str.toUpperCase();
+ if (ch.formatFunction == "downcase")
+ return str.toLowerCase();
+ return str;
+ };
+
+ this.resolveVariables = function(snippet, editor) {
+ var result = [];
+ var indentation = "";
+ var afterNewLine = true;
+ for (var i = 0; i < snippet.length; i++) {
+ var ch = snippet[i];
+ if (typeof ch == "string") {
+ result.push(ch);
+ if (ch == "\n") {
+ afterNewLine = true;
+ indentation = "";
+ }
+ else if (afterNewLine) {
+ indentation = /^\t*/.exec(ch)[0];
+ afterNewLine = /\S/.test(ch);
+ }
+ continue;
+ }
+ if (!ch) continue;
+ afterNewLine = false;
+
+ if (ch.fmtString) {
+ var j = snippet.indexOf(ch, i + 1);
+ if (j == -1) j = snippet.length;
+ ch.fmt = snippet.slice(i + 1, j);
+ i = j;
+ }
+
+ if (ch.text) {
+ var value = this.getVariableValue(editor, ch.text, indentation) + "";
+ if (ch.fmtString)
+ value = this.tmStrFormat(value, ch, editor);
+ if (ch.formatFunction)
+ value = this.tmFormatFunction(value, ch, editor);
+
+ if (value && !ch.ifEnd) {
+ result.push(value);
+ gotoNext(ch);
+ } else if (!value && ch.ifEnd) {
+ gotoNext(ch.ifEnd);
+ }
+ } else if (ch.elseEnd) {
+ gotoNext(ch.elseEnd);
+ } else if (ch.tabstopId != null) {
+ result.push(ch);
+ } else if (ch.changeCase != null) {
+ result.push(ch);
+ }
+ }
+ function gotoNext(ch) {
+ var i1 = snippet.indexOf(ch, i + 1);
+ if (i1 != -1)
+ i = i1;
+ }
+ return result;
+ };
+
+ this.insertSnippetForSelection = function(editor, snippetText) {
+ var cursor = editor.getCursorPosition();
+ var line = editor.session.getLine(cursor.row);
+ var tabString = editor.session.getTabString();
+ var indentString = line.match(/^\s*/)[0];
+
+ if (cursor.column < indentString.length)
+ indentString = indentString.slice(0, cursor.column);
+
+ snippetText = snippetText.replace(/\r/g, "");
+ var tokens = this.tokenizeTmSnippet(snippetText);
+ tokens = this.resolveVariables(tokens, editor);
+ tokens = tokens.map(function(x) {
+ if (x == "\n")
+ return x + indentString;
+ if (typeof x == "string")
+ return x.replace(/\t/g, tabString);
+ return x;
+ });
+ var tabstops = [];
+ tokens.forEach(function(p, i) {
+ if (typeof p != "object")
+ return;
+ var id = p.tabstopId;
+ var ts = tabstops[id];
+ if (!ts) {
+ ts = tabstops[id] = [];
+ ts.index = id;
+ ts.value = "";
+ ts.parents = {};
+ }
+ if (ts.indexOf(p) !== -1)
+ return;
+ if (p.choices && !ts.choices)
+ ts.choices = p.choices;
+ ts.push(p);
+ var i1 = tokens.indexOf(p, i + 1);
+ if (i1 === -1)
+ return;
+
+ var value = tokens.slice(i + 1, i1);
+ var isNested = value.some(function(t) {return typeof t === "object";});
+ if (isNested && !ts.value) {
+ ts.value = value;
+ } else if (value.length && (!ts.value || typeof ts.value !== "string")) {
+ ts.value = value.join("");
+ }
+ });
+ tabstops.forEach(function(ts) {ts.length = 0;});
+ var expanding = {};
+ function copyValue(val) {
+ var copy = [];
+ for (var i = 0; i < val.length; i++) {
+ var p = val[i];
+ if (typeof p == "object") {
+ if (expanding[p.tabstopId])
+ continue;
+ var j = val.lastIndexOf(p, i - 1);
+ p = copy[j] || {tabstopId: p.tabstopId};
+ }
+ copy[i] = p;
+ }
+ return copy;
+ }
+ for (var i = 0; i < tokens.length; i++) {
+ var p = tokens[i];
+ if (typeof p != "object")
+ continue;
+ var id = p.tabstopId;
+ var ts = tabstops[id];
+ var i1 = tokens.indexOf(p, i + 1);
+ if (expanding[id]) {
+ if (expanding[id] === p) {
+ delete expanding[id];
+ Object.keys(expanding).forEach(function(parentId) {
+ ts.parents[parentId] = true;
+ });
+ }
+ continue;
+ }
+ expanding[id] = p;
+ var value = ts.value;
+ if (typeof value !== "string")
+ value = copyValue(value);
+ else if (p.fmt)
+ value = this.tmStrFormat(value, p, editor);
+ tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));
+
+ if (ts.indexOf(p) === -1)
+ ts.push(p);
+ }
+ var row = 0, column = 0;
+ var text = "";
+ tokens.forEach(function(t) {
+ if (typeof t === "string") {
+ var lines = t.split("\n");
+ if (lines.length > 1){
+ column = lines[lines.length - 1].length;
+ row += lines.length - 1;
+ } else
+ column += t.length;
+ text += t;
+ } else if (t) {
+ if (!t.start)
+ t.start = {row: row, column: column};
+ else
+ t.end = {row: row, column: column};
+ }
+ });
+ var range = editor.getSelectionRange();
+ var end = editor.session.replace(range, text);
+
+ var tabstopManager = new TabstopManager(editor);
+ var selectionId = editor.inVirtualSelectionMode && editor.selection.index;
+ tabstopManager.addTabstops(tabstops, range.start, end, selectionId);
+ };
+
+ this.insertSnippet = function(editor, snippetText) {
+ var self = this;
+ if (editor.inVirtualSelectionMode)
+ return self.insertSnippetForSelection(editor, snippetText);
+
+ editor.forEachSelection(function() {
+ self.insertSnippetForSelection(editor, snippetText);
+ }, null, {keepOrder: true});
+
+ if (editor.tabstopManager)
+ editor.tabstopManager.tabNext();
+ };
+
+ this.$getScope = function(editor) {
+ var scope = editor.session.$mode.$id || "";
+ scope = scope.split("/").pop();
+ if (scope === "html" || scope === "php") {
+ if (scope === "php" && !editor.session.$mode.inlinePhp)
+ scope = "html";
+ var c = editor.getCursorPosition();
+ var state = editor.session.getState(c.row);
+ if (typeof state === "object") {
+ state = state[0];
+ }
+ if (state.substring) {
+ if (state.substring(0, 3) == "js-")
+ scope = "javascript";
+ else if (state.substring(0, 4) == "css-")
+ scope = "css";
+ else if (state.substring(0, 4) == "php-")
+ scope = "php";
+ }
+ }
+
+ return scope;
+ };
+
+ this.getActiveScopes = function(editor) {
+ var scope = this.$getScope(editor);
+ var scopes = [scope];
+ var snippetMap = this.snippetMap;
+ if (snippetMap[scope] && snippetMap[scope].includeScopes) {
+ scopes.push.apply(scopes, snippetMap[scope].includeScopes);
+ }
+ scopes.push("_");
+ return scopes;
+ };
+
+ this.expandWithTab = function(editor, options) {
+ var self = this;
+ var result = editor.forEachSelection(function() {
+ return self.expandSnippetForSelection(editor, options);
+ }, null, {keepOrder: true});
+ if (result && editor.tabstopManager)
+ editor.tabstopManager.tabNext();
+ return result;
+ };
+
+ this.expandSnippetForSelection = function(editor, options) {
+ var cursor = editor.getCursorPosition();
+ var line = editor.session.getLine(cursor.row);
+ var before = line.substring(0, cursor.column);
+ var after = line.substr(cursor.column);
+
+ var snippetMap = this.snippetMap;
+ var snippet;
+ this.getActiveScopes(editor).some(function(scope) {
+ var snippets = snippetMap[scope];
+ if (snippets)
+ snippet = this.findMatchingSnippet(snippets, before, after);
+ return !!snippet;
+ }, this);
+ if (!snippet)
+ return false;
+ if (options && options.dryRun)
+ return true;
+ editor.session.doc.removeInLine(cursor.row,
+ cursor.column - snippet.replaceBefore.length,
+ cursor.column + snippet.replaceAfter.length
+ );
+
+ this.variables.M__ = snippet.matchBefore;
+ this.variables.T__ = snippet.matchAfter;
+ this.insertSnippetForSelection(editor, snippet.content);
+
+ this.variables.M__ = this.variables.T__ = null;
+ return true;
+ };
+
+ this.findMatchingSnippet = function(snippetList, before, after) {
+ for (var i = snippetList.length; i--;) {
+ var s = snippetList[i];
+ if (s.startRe && !s.startRe.test(before))
+ continue;
+ if (s.endRe && !s.endRe.test(after))
+ continue;
+ if (!s.startRe && !s.endRe)
+ continue;
+
+ s.matchBefore = s.startRe ? s.startRe.exec(before) : [""];
+ s.matchAfter = s.endRe ? s.endRe.exec(after) : [""];
+ s.replaceBefore = s.triggerRe ? s.triggerRe.exec(before)[0] : "";
+ s.replaceAfter = s.endTriggerRe ? s.endTriggerRe.exec(after)[0] : "";
+ return s;
+ }
+ };
+
+ this.snippetMap = {};
+ this.snippetNameMap = {};
+ this.register = function(snippets, scope) {
+ var snippetMap = this.snippetMap;
+ var snippetNameMap = this.snippetNameMap;
+ var self = this;
+
+ if (!snippets)
+ snippets = [];
+
+ function wrapRegexp(src) {
+ if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src))
+ src = "(?:" + src + ")";
+
+ return src || "";
+ }
+ function guardedRegexp(re, guard, opening) {
+ re = wrapRegexp(re);
+ guard = wrapRegexp(guard);
+ if (opening) {
+ re = guard + re;
+ if (re && re[re.length - 1] != "$")
+ re = re + "$";
+ } else {
+ re = re + guard;
+ if (re && re[0] != "^")
+ re = "^" + re;
+ }
+ return new RegExp(re);
+ }
+
+ function addSnippet(s) {
+ if (!s.scope)
+ s.scope = scope || "_";
+ scope = s.scope;
+ if (!snippetMap[scope]) {
+ snippetMap[scope] = [];
+ snippetNameMap[scope] = {};
+ }
+
+ var map = snippetNameMap[scope];
+ if (s.name) {
+ var old = map[s.name];
+ if (old)
+ self.unregister(old);
+ map[s.name] = s;
+ }
+ snippetMap[scope].push(s);
+
+ if (s.tabTrigger && !s.trigger) {
+ if (!s.guard && /^\w/.test(s.tabTrigger))
+ s.guard = "\\b";
+ s.trigger = lang.escapeRegExp(s.tabTrigger);
+ }
+
+ if (!s.trigger && !s.guard && !s.endTrigger && !s.endGuard)
+ return;
+
+ s.startRe = guardedRegexp(s.trigger, s.guard, true);
+ s.triggerRe = new RegExp(s.trigger);
+
+ s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true);
+ s.endTriggerRe = new RegExp(s.endTrigger);
+ }
+
+ if (snippets && snippets.content)
+ addSnippet(snippets);
+ else if (Array.isArray(snippets))
+ snippets.forEach(addSnippet);
+
+ this._signal("registerSnippets", {scope: scope});
+ };
+ this.unregister = function(snippets, scope) {
+ var snippetMap = this.snippetMap;
+ var snippetNameMap = this.snippetNameMap;
+
+ function removeSnippet(s) {
+ var nameMap = snippetNameMap[s.scope||scope];
+ if (nameMap && nameMap[s.name]) {
+ delete nameMap[s.name];
+ var map = snippetMap[s.scope||scope];
+ var i = map && map.indexOf(s);
+ if (i >= 0)
+ map.splice(i, 1);
+ }
+ }
+ if (snippets.content)
+ removeSnippet(snippets);
+ else if (Array.isArray(snippets))
+ snippets.forEach(removeSnippet);
+ };
+ this.parseSnippetFile = function(str) {
+ str = str.replace(/\r/g, "");
+ var list = [], snippet = {};
+ var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
+ var m;
+ while (m = re.exec(str)) {
+ if (m[1]) {
+ try {
+ snippet = JSON.parse(m[1]);
+ list.push(snippet);
+ } catch (e) {}
+ } if (m[4]) {
+ snippet.content = m[4].replace(/^\t/gm, "");
+ list.push(snippet);
+ snippet = {};
+ } else {
+ var key = m[2], val = m[3];
+ if (key == "regex") {
+ var guardRe = /\/((?:[^\/\\]|\\.)*)|$/g;
+ snippet.guard = guardRe.exec(val)[1];
+ snippet.trigger = guardRe.exec(val)[1];
+ snippet.endTrigger = guardRe.exec(val)[1];
+ snippet.endGuard = guardRe.exec(val)[1];
+ } else if (key == "snippet") {
+ snippet.tabTrigger = val.match(/^\S*/)[0];
+ if (!snippet.name)
+ snippet.name = val;
+ } else {
+ snippet[key] = val;
+ }
+ }
+ }
+ return list;
+ };
+ this.getSnippetByName = function(name, editor) {
+ var snippetMap = this.snippetNameMap;
+ var snippet;
+ this.getActiveScopes(editor).some(function(scope) {
+ var snippets = snippetMap[scope];
+ if (snippets)
+ snippet = snippets[name];
+ return !!snippet;
+ }, this);
+ return snippet;
+ };
+
+}).call(SnippetManager.prototype);
+
+
+var TabstopManager = function(editor) {
+ if (editor.tabstopManager)
+ return editor.tabstopManager;
+ editor.tabstopManager = this;
+ this.$onChange = this.onChange.bind(this);
+ this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;
+ this.$onChangeSession = this.onChangeSession.bind(this);
+ this.$onAfterExec = this.onAfterExec.bind(this);
+ this.attach(editor);
+};
+(function() {
+ this.attach = function(editor) {
+ this.index = 0;
+ this.ranges = [];
+ this.tabstops = [];
+ this.$openTabstops = null;
+ this.selectedTabstop = null;
+
+ this.editor = editor;
+ this.editor.on("change", this.$onChange);
+ this.editor.on("changeSelection", this.$onChangeSelection);
+ this.editor.on("changeSession", this.$onChangeSession);
+ this.editor.commands.on("afterExec", this.$onAfterExec);
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
+ };
+ this.detach = function() {
+ this.tabstops.forEach(this.removeTabstopMarkers, this);
+ this.ranges = null;
+ this.tabstops = null;
+ this.selectedTabstop = null;
+ this.editor.removeListener("change", this.$onChange);
+ this.editor.removeListener("changeSelection", this.$onChangeSelection);
+ this.editor.removeListener("changeSession", this.$onChangeSession);
+ this.editor.commands.removeListener("afterExec", this.$onAfterExec);
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
+ this.editor.tabstopManager = null;
+ this.editor = null;
+ };
+
+ this.onChange = function(delta) {
+ var isRemove = delta.action[0] == "r";
+ var selectedTabstop = this.selectedTabstop || {};
+ var parents = selectedTabstop.parents || {};
+ var tabstops = (this.tabstops || []).slice();
+ for (var i = 0; i < tabstops.length; i++) {
+ var ts = tabstops[i];
+ var active = ts == selectedTabstop || parents[ts.index];
+ ts.rangeList.$bias = active ? 0 : 1;
+
+ if (delta.action == "remove" && ts !== selectedTabstop) {
+ var parentActive = ts.parents && ts.parents[selectedTabstop.index];
+ var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
+ startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
+ var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
+ endIndex = endIndex < 0 ? -endIndex - 1 : endIndex - 1;
+ var toRemove = ts.rangeList.ranges.slice(startIndex, endIndex);
+ for (var j = 0; j < toRemove.length; j++)
+ this.removeRange(toRemove[j]);
+ }
+ ts.rangeList.$onChange(delta);
+ }
+ var session = this.editor.session;
+ if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())
+ this.detach();
+ };
+ this.updateLinkedFields = function() {
+ var ts = this.selectedTabstop;
+ if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)
+ return;
+ this.$inChange = true;
+ var session = this.editor.session;
+ var text = session.getTextRange(ts.firstNonLinked);
+ for (var i = 0; i < ts.length; i++) {
+ var range = ts[i];
+ if (!range.linked)
+ continue;
+ var original = range.original;
+ var fmt = exports.snippetManager.tmStrFormat(text, original, this.editor);
+ session.replace(range, fmt);
+ }
+ this.$inChange = false;
+ };
+ this.onAfterExec = function(e) {
+ if (e.command && !e.command.readOnly)
+ this.updateLinkedFields();
+ };
+ this.onChangeSelection = function() {
+ if (!this.editor)
+ return;
+ var lead = this.editor.selection.lead;
+ var anchor = this.editor.selection.anchor;
+ var isEmpty = this.editor.selection.isEmpty();
+ for (var i = 0; i < this.ranges.length; i++) {
+ if (this.ranges[i].linked)
+ continue;
+ var containsLead = this.ranges[i].contains(lead.row, lead.column);
+ var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
+ if (containsLead && containsAnchor)
+ return;
+ }
+ this.detach();
+ };
+ this.onChangeSession = function() {
+ this.detach();
+ };
+ this.tabNext = function(dir) {
+ var max = this.tabstops.length;
+ var index = this.index + (dir || 1);
+ index = Math.min(Math.max(index, 1), max);
+ if (index == max)
+ index = 0;
+ this.selectTabstop(index);
+ if (index === 0)
+ this.detach();
+ };
+ this.selectTabstop = function(index) {
+ this.$openTabstops = null;
+ var ts = this.tabstops[this.index];
+ if (ts)
+ this.addTabstopMarkers(ts);
+ this.index = index;
+ ts = this.tabstops[this.index];
+ if (!ts || !ts.length)
+ return;
+
+ this.selectedTabstop = ts;
+ var range = ts.firstNonLinked || ts;
+ if (!this.editor.inVirtualSelectionMode) {
+ var sel = this.editor.multiSelect;
+ sel.toSingleRange(range.clone());
+ for (var i = 0; i < ts.length; i++) {
+ if (ts.hasLinkedRanges && ts[i].linked)
+ continue;
+ sel.addRange(ts[i].clone(), true);
+ }
+ if (sel.ranges[0])
+ sel.addRange(sel.ranges[0].clone());
+ } else {
+ this.editor.selection.setRange(range);
+ }
+
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
+ if (this.selectedTabstop && this.selectedTabstop.choices)
+ this.editor.execCommand("startAutocomplete", {matches: this.selectedTabstop.choices});
+ };
+ this.addTabstops = function(tabstops, start, end) {
+ var useLink = this.useLink || !this.editor.getOption("enableMultiselect");
+
+ if (!this.$openTabstops)
+ this.$openTabstops = [];
+ if (!tabstops[0]) {
+ var p = Range.fromPoints(end, end);
+ moveRelative(p.start, start);
+ moveRelative(p.end, start);
+ tabstops[0] = [p];
+ tabstops[0].index = 0;
+ }
+
+ var i = this.index;
+ var arg = [i + 1, 0];
+ var ranges = this.ranges;
+ tabstops.forEach(function(ts, index) {
+ var dest = this.$openTabstops[index] || ts;
+
+ for (var i = 0; i < ts.length; i++) {
+ var p = ts[i];
+ var range = Range.fromPoints(p.start, p.end || p.start);
+ movePoint(range.start, start);
+ movePoint(range.end, start);
+ range.original = p;
+ range.tabstop = dest;
+ ranges.push(range);
+ if (dest != ts)
+ dest.unshift(range);
+ else
+ dest[i] = range;
+ if (p.fmtString || (dest.firstNonLinked && useLink)) {
+ range.linked = true;
+ dest.hasLinkedRanges = true;
+ } else if (!dest.firstNonLinked)
+ dest.firstNonLinked = range;
+ }
+ if (!dest.firstNonLinked)
+ dest.hasLinkedRanges = false;
+ if (dest === ts) {
+ arg.push(dest);
+ this.$openTabstops[index] = dest;
+ }
+ this.addTabstopMarkers(dest);
+ dest.rangeList = dest.rangeList || new RangeList();
+ dest.rangeList.$bias = 0;
+ dest.rangeList.addList(dest);
+ }, this);
+
+ if (arg.length > 2) {
+ if (this.tabstops.length)
+ arg.push(arg.splice(2, 1)[0]);
+ this.tabstops.splice.apply(this.tabstops, arg);
+ }
+ };
+
+ this.addTabstopMarkers = function(ts) {
+ var session = this.editor.session;
+ ts.forEach(function(range) {
+ if (!range.markerId)
+ range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
+ });
+ };
+ this.removeTabstopMarkers = function(ts) {
+ var session = this.editor.session;
+ ts.forEach(function(range) {
+ session.removeMarker(range.markerId);
+ range.markerId = null;
+ });
+ };
+ this.removeRange = function(range) {
+ var i = range.tabstop.indexOf(range);
+ if (i != -1) range.tabstop.splice(i, 1);
+ i = this.ranges.indexOf(range);
+ if (i != -1) this.ranges.splice(i, 1);
+ i = range.tabstop.rangeList.ranges.indexOf(range);
+ if (i != -1) range.tabstop.splice(i, 1);
+ this.editor.session.removeMarker(range.markerId);
+ if (!range.tabstop.length) {
+ i = this.tabstops.indexOf(range.tabstop);
+ if (i != -1)
+ this.tabstops.splice(i, 1);
+ if (!this.tabstops.length)
+ this.detach();
+ }
+ };
+
+ this.keyboardHandler = new HashHandler();
+ this.keyboardHandler.bindKeys({
+ "Tab": function(editor) {
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
+ return;
+ editor.tabstopManager.tabNext(1);
+ editor.renderer.scrollCursorIntoView();
+ },
+ "Shift-Tab": function(editor) {
+ editor.tabstopManager.tabNext(-1);
+ editor.renderer.scrollCursorIntoView();
+ },
+ "Esc": function(editor) {
+ editor.tabstopManager.detach();
+ }
+ });
+}).call(TabstopManager.prototype);
+
+
+
+var movePoint = function(point, diff) {
+ if (point.row == 0)
+ point.column += diff.column;
+ point.row += diff.row;
+};
+
+var moveRelative = function(point, start) {
+ if (point.row == start.row)
+ point.column -= start.column;
+ point.row -= start.row;
+};
+
+
+require("./lib/dom").importCssString("\
+.ace_snippet-marker {\
+ -moz-box-sizing: border-box;\
+ box-sizing: border-box;\
+ background: rgba(194, 193, 208, 0.09);\
+ border: 1px dotted rgba(211, 208, 235, 0.62);\
+ position: absolute;\
+}");
+
+exports.snippetManager = new SnippetManager();
+
+
+var Editor = require("./editor").Editor;
+(function() {
+ this.insertSnippet = function(content, options) {
+ return exports.snippetManager.insertSnippet(this, content, options);
+ };
+ this.expandSnippet = function(options) {
+ return exports.snippetManager.expandWithTab(this, options);
+ };
+}).call(Editor.prototype);
+
+});
+
+define("ace/ext/emmet",["require","exports","module","ace/keyboard/hash_handler","ace/editor","ace/snippets","ace/range","ace/config","resources","resources","tabStops","resources","utils","actions"], function(require, exports, module) {
+"use strict";
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var Editor = require("../editor").Editor;
+var snippetManager = require("../snippets").snippetManager;
+var Range = require("../range").Range;
+var config = require("../config");
+var emmet, emmetPath;
+function AceEmmetEditor() {}
+
+AceEmmetEditor.prototype = {
+ setupContext: function(editor) {
+ this.ace = editor;
+ this.indentation = editor.session.getTabString();
+ if (!emmet)
+ emmet = window.emmet;
+ var resources = emmet.resources || emmet.require("resources");
+ resources.setVariable("indentation", this.indentation);
+ this.$syntax = null;
+ this.$syntax = this.getSyntax();
+ },
+ getSelectionRange: function() {
+ var range = this.ace.getSelectionRange();
+ var doc = this.ace.session.doc;
+ return {
+ start: doc.positionToIndex(range.start),
+ end: doc.positionToIndex(range.end)
+ };
+ },
+ createSelection: function(start, end) {
+ var doc = this.ace.session.doc;
+ this.ace.selection.setRange({
+ start: doc.indexToPosition(start),
+ end: doc.indexToPosition(end)
+ });
+ },
+ getCurrentLineRange: function() {
+ var ace = this.ace;
+ var row = ace.getCursorPosition().row;
+ var lineLength = ace.session.getLine(row).length;
+ var index = ace.session.doc.positionToIndex({row: row, column: 0});
+ return {
+ start: index,
+ end: index + lineLength
+ };
+ },
+ getCaretPos: function(){
+ var pos = this.ace.getCursorPosition();
+ return this.ace.session.doc.positionToIndex(pos);
+ },
+ setCaretPos: function(index){
+ var pos = this.ace.session.doc.indexToPosition(index);
+ this.ace.selection.moveToPosition(pos);
+ },
+ getCurrentLine: function() {
+ var row = this.ace.getCursorPosition().row;
+ return this.ace.session.getLine(row);
+ },
+ replaceContent: function(value, start, end, noIndent) {
+ if (end == null)
+ end = start == null ? this.getContent().length : start;
+ if (start == null)
+ start = 0;
+
+ var editor = this.ace;
+ var doc = editor.session.doc;
+ var range = Range.fromPoints(doc.indexToPosition(start), doc.indexToPosition(end));
+ editor.session.remove(range);
+
+ range.end = range.start;
+
+ value = this.$updateTabstops(value);
+ snippetManager.insertSnippet(editor, value);
+ },
+ getContent: function(){
+ return this.ace.getValue();
+ },
+ getSyntax: function() {
+ if (this.$syntax)
+ return this.$syntax;
+ var syntax = this.ace.session.$modeId.split("/").pop();
+ if (syntax == "html" || syntax == "php") {
+ var cursor = this.ace.getCursorPosition();
+ var state = this.ace.session.getState(cursor.row);
+ if (typeof state != "string")
+ state = state[0];
+ if (state) {
+ state = state.split("-");
+ if (state.length > 1)
+ syntax = state[0];
+ else if (syntax == "php")
+ syntax = "html";
+ }
+ }
+ return syntax;
+ },
+ getProfileName: function() {
+ var resources = emmet.resources || emmet.require("resources");
+ switch (this.getSyntax()) {
+ case "css": return "css";
+ case "xml":
+ case "xsl":
+ return "xml";
+ case "html":
+ var profile = resources.getVariable("profile");
+ if (!profile)
+ profile = this.ace.session.getLines(0,2).join("").search(/]+XHTML/i) != -1 ? "xhtml": "html";
+ return profile;
+ default:
+ var mode = this.ace.session.$mode;
+ return mode.emmetConfig && mode.emmetConfig.profile || "xhtml";
+ }
+ },
+ prompt: function(title) {
+ return prompt(title); // eslint-disable-line no-alert
+ },
+ getSelection: function() {
+ return this.ace.session.getTextRange();
+ },
+ getFilePath: function() {
+ return "";
+ },
+ $updateTabstops: function(value) {
+ var base = 1000;
+ var zeroBase = 0;
+ var lastZero = null;
+ var ts = emmet.tabStops || emmet.require('tabStops');
+ var resources = emmet.resources || emmet.require("resources");
+ var settings = resources.getVocabulary("user");
+ var tabstopOptions = {
+ tabstop: function(data) {
+ var group = parseInt(data.group, 10);
+ var isZero = group === 0;
+ if (isZero)
+ group = ++zeroBase;
+ else
+ group += base;
+
+ var placeholder = data.placeholder;
+ if (placeholder) {
+ placeholder = ts.processText(placeholder, tabstopOptions);
+ }
+
+ var result = '${' + group + (placeholder ? ':' + placeholder : '') + '}';
+
+ if (isZero) {
+ lastZero = [data.start, result];
+ }
+
+ return result;
+ },
+ escape: function(ch) {
+ if (ch == '$') return '\\$';
+ if (ch == '\\') return '\\\\';
+ return ch;
+ }
+ };
+
+ value = ts.processText(value, tabstopOptions);
+
+ if (settings.variables['insert_final_tabstop'] && !/\$\{0\}$/.test(value)) {
+ value += '${0}';
+ } else if (lastZero) {
+ var common = emmet.utils ? emmet.utils.common : emmet.require('utils');
+ value = common.replaceSubstring(value, '${0}', lastZero[0], lastZero[1]);
+ }
+
+ return value;
+ }
+};
+
+
+var keymap = {
+ expand_abbreviation: {"mac": "ctrl+alt+e", "win": "alt+e"},
+ match_pair_outward: {"mac": "ctrl+d", "win": "ctrl+,"},
+ match_pair_inward: {"mac": "ctrl+j", "win": "ctrl+shift+0"},
+ matching_pair: {"mac": "ctrl+alt+j", "win": "alt+j"},
+ next_edit_point: "alt+right",
+ prev_edit_point: "alt+left",
+ toggle_comment: {"mac": "command+/", "win": "ctrl+/"},
+ split_join_tag: {"mac": "shift+command+'", "win": "shift+ctrl+`"},
+ remove_tag: {"mac": "command+'", "win": "shift+ctrl+;"},
+ evaluate_math_expression: {"mac": "shift+command+y", "win": "shift+ctrl+y"},
+ increment_number_by_1: "ctrl+up",
+ decrement_number_by_1: "ctrl+down",
+ increment_number_by_01: "alt+up",
+ decrement_number_by_01: "alt+down",
+ increment_number_by_10: {"mac": "alt+command+up", "win": "shift+alt+up"},
+ decrement_number_by_10: {"mac": "alt+command+down", "win": "shift+alt+down"},
+ select_next_item: {"mac": "shift+command+.", "win": "shift+ctrl+."},
+ select_previous_item: {"mac": "shift+command+,", "win": "shift+ctrl+,"},
+ reflect_css_value: {"mac": "shift+command+r", "win": "shift+ctrl+r"},
+
+ encode_decode_data_url: {"mac": "shift+ctrl+d", "win": "ctrl+'"},
+ expand_abbreviation_with_tab: "Tab",
+ wrap_with_abbreviation: {"mac": "shift+ctrl+a", "win": "shift+ctrl+a"}
+};
+
+var editorProxy = new AceEmmetEditor();
+exports.commands = new HashHandler();
+exports.runEmmetCommand = function runEmmetCommand(editor) {
+ if (this.action == "expand_abbreviation_with_tab") {
+ if (!editor.selection.isEmpty())
+ return false;
+ var pos = editor.selection.lead;
+ var token = editor.session.getTokenAt(pos.row, pos.column);
+ if (token && /\btag\b/.test(token.type))
+ return false;
+ }
+ try {
+ editorProxy.setupContext(editor);
+ var actions = emmet.actions || emmet.require("actions");
+
+ if (this.action == "wrap_with_abbreviation") {
+ return setTimeout(function() {
+ actions.run("wrap_with_abbreviation", editorProxy);
+ }, 0);
+ }
+
+ var result = actions.run(this.action, editorProxy);
+ } catch(e) {
+ if (!emmet) {
+ var loading = exports.load(runEmmetCommand.bind(this, editor));
+ if (this.action == "expand_abbreviation_with_tab")
+ return false;
+ return loading;
+ }
+ editor._signal("changeStatus", typeof e == "string" ? e : e.message);
+ config.warn(e);
+ result = false;
+ }
+ return result;
+};
+
+for (var command in keymap) {
+ exports.commands.addCommand({
+ name: "emmet:" + command,
+ action: command,
+ bindKey: keymap[command],
+ exec: exports.runEmmetCommand,
+ multiSelectAction: "forEach"
+ });
+}
+
+exports.updateCommands = function(editor, enabled) {
+ if (enabled) {
+ editor.keyBinding.addKeyboardHandler(exports.commands);
+ } else {
+ editor.keyBinding.removeKeyboardHandler(exports.commands);
+ }
+};
+
+exports.isSupportedMode = function(mode) {
+ if (!mode) return false;
+ if (mode.emmetConfig) return true;
+ var id = mode.$id || mode;
+ return /css|less|scss|sass|stylus|html|php|twig|ejs|handlebars/.test(id);
+};
+
+exports.isAvailable = function(editor, command) {
+ if (/(evaluate_math_expression|expand_abbreviation)$/.test(command))
+ return true;
+ var mode = editor.session.$mode;
+ var isSupported = exports.isSupportedMode(mode);
+ if (isSupported && mode.$modes) {
+ try {
+ editorProxy.setupContext(editor);
+ if (/js|php/.test(editorProxy.getSyntax()))
+ isSupported = false;
+ } catch(e) {}
+ }
+ return isSupported;
+};
+
+var onChangeMode = function(e, target) {
+ var editor = target;
+ if (!editor)
+ return;
+ var enabled = exports.isSupportedMode(editor.session.$mode);
+ if (e.enableEmmet === false)
+ enabled = false;
+ if (enabled)
+ exports.load();
+ exports.updateCommands(editor, enabled);
+};
+
+exports.load = function(cb) {
+ if (typeof emmetPath !== "string") {
+ config.warn("script for emmet-core is not loaded");
+ return false;
+ }
+ config.loadModule(emmetPath, function() {
+ emmetPath = null;
+ cb && cb();
+ });
+ return true;
+};
+
+exports.AceEmmetEditor = AceEmmetEditor;
+config.defineOptions(Editor.prototype, "editor", {
+ enableEmmet: {
+ set: function(val) {
+ this[val ? "on" : "removeListener"]("changeMode", onChangeMode);
+ onChangeMode({enableEmmet: !!val}, this);
+ },
+ value: true
+ }
+});
+
+exports.setCore = function(e) {
+ if (typeof e == "string")
+ emmetPath = e;
+ else
+ emmet = e;
+};
+});
+
+define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"], function(require, exports, module) {
+"use strict";
+
+var Renderer = require("../virtual_renderer").VirtualRenderer;
+var Editor = require("../editor").Editor;
+var Range = require("../range").Range;
+var event = require("../lib/event");
+var lang = require("../lib/lang");
+var dom = require("../lib/dom");
+
+var $singleLineEditor = function(el) {
+ var renderer = new Renderer(el);
+
+ renderer.$maxLines = 4;
+
+ var editor = new Editor(renderer);
+
+ editor.setHighlightActiveLine(false);
+ editor.setShowPrintMargin(false);
+ editor.renderer.setShowGutter(false);
+ editor.renderer.setHighlightGutterLine(false);
+
+ editor.$mouseHandler.$focusTimeout = 0;
+ editor.$highlightTagPending = true;
+
+ return editor;
+};
+
+var AcePopup = function(parentNode) {
+ var el = dom.createElement("div");
+ var popup = new $singleLineEditor(el);
+
+ if (parentNode)
+ parentNode.appendChild(el);
+ el.style.display = "none";
+ popup.renderer.content.style.cursor = "default";
+ popup.renderer.setStyle("ace_autocomplete");
+
+ popup.setOption("displayIndentGuides", false);
+ popup.setOption("dragDelay", 150);
+
+ var noop = function(){};
+
+ popup.focus = noop;
+ popup.$isFocused = true;
+
+ popup.renderer.$cursorLayer.restartTimer = noop;
+ popup.renderer.$cursorLayer.element.style.opacity = 0;
+
+ popup.renderer.$maxLines = 8;
+ popup.renderer.$keepTextAreaAtCursor = false;
+
+ popup.setHighlightActiveLine(false);
+ popup.session.highlight("");
+ popup.session.$searchHighlight.clazz = "ace_highlight-marker";
+
+ popup.on("mousedown", function(e) {
+ var pos = e.getDocumentPosition();
+ popup.selection.moveToPosition(pos);
+ selectionMarker.start.row = selectionMarker.end.row = pos.row;
+ e.stop();
+ });
+
+ var lastMouseEvent;
+ var hoverMarker = new Range(-1,0,-1,Infinity);
+ var selectionMarker = new Range(-1,0,-1,Infinity);
+ selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine");
+ popup.setSelectOnHover = function(val) {
+ if (!val) {
+ hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine");
+ } else if (hoverMarker.id) {
+ popup.session.removeMarker(hoverMarker.id);
+ hoverMarker.id = null;
+ }
+ };
+ popup.setSelectOnHover(false);
+ popup.on("mousemove", function(e) {
+ if (!lastMouseEvent) {
+ lastMouseEvent = e;
+ return;
+ }
+ if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {
+ return;
+ }
+ lastMouseEvent = e;
+ lastMouseEvent.scrollTop = popup.renderer.scrollTop;
+ var row = lastMouseEvent.getDocumentPosition().row;
+ if (hoverMarker.start.row != row) {
+ if (!hoverMarker.id)
+ popup.setRow(row);
+ setHoverMarker(row);
+ }
+ });
+ popup.renderer.on("beforeRender", function() {
+ if (lastMouseEvent && hoverMarker.start.row != -1) {
+ lastMouseEvent.$pos = null;
+ var row = lastMouseEvent.getDocumentPosition().row;
+ if (!hoverMarker.id)
+ popup.setRow(row);
+ setHoverMarker(row, true);
+ }
+ });
+ popup.renderer.on("afterRender", function() {
+ var row = popup.getRow();
+ var t = popup.renderer.$textLayer;
+ var selected = t.element.childNodes[row - t.config.firstRow];
+ if (selected !== t.selectedNode && t.selectedNode)
+ dom.removeCssClass(t.selectedNode, "ace_selected");
+ t.selectedNode = selected;
+ if (selected)
+ dom.addCssClass(selected, "ace_selected");
+ });
+ var hideHoverMarker = function() { setHoverMarker(-1); };
+ var setHoverMarker = function(row, suppressRedraw) {
+ if (row !== hoverMarker.start.row) {
+ hoverMarker.start.row = hoverMarker.end.row = row;
+ if (!suppressRedraw)
+ popup.session._emit("changeBackMarker");
+ popup._emit("changeHoverMarker");
+ }
+ };
+ popup.getHoveredRow = function() {
+ return hoverMarker.start.row;
+ };
+
+ event.addListener(popup.container, "mouseout", hideHoverMarker);
+ popup.on("hide", hideHoverMarker);
+ popup.on("changeSelection", hideHoverMarker);
+
+ popup.session.doc.getLength = function() {
+ return popup.data.length;
+ };
+ popup.session.doc.getLine = function(i) {
+ var data = popup.data[i];
+ if (typeof data == "string")
+ return data;
+ return (data && data.value) || "";
+ };
+
+ var bgTokenizer = popup.session.bgTokenizer;
+ bgTokenizer.$tokenizeRow = function(row) {
+ var data = popup.data[row];
+ var tokens = [];
+ if (!data)
+ return tokens;
+ if (typeof data == "string")
+ data = {value: data};
+ var caption = data.caption || data.value || data.name;
+
+ function addToken(value, className) {
+ value && tokens.push({
+ type: (data.className || "") + (className || ""),
+ value: value
+ });
+ }
+
+ var lower = caption.toLowerCase();
+ var filterText = (popup.filterText || "").toLowerCase();
+ var lastIndex = 0;
+ var lastI = 0;
+ for (var i = 0; i <= filterText.length; i++) {
+ if (i != lastI && (data.matchMask & (1 << i) || i == filterText.length)) {
+ var sub = filterText.slice(lastI, i);
+ lastI = i;
+ var index = lower.indexOf(sub, lastIndex);
+ if (index == -1) continue;
+ addToken(caption.slice(lastIndex, index), "");
+ lastIndex = index + sub.length;
+ addToken(caption.slice(index, lastIndex), "completion-highlight");
+ }
+ }
+ addToken(caption.slice(lastIndex, caption.length), "");
+
+ if (data.meta)
+ tokens.push({type: "completion-meta", value: data.meta});
+ if (data.message)
+ tokens.push({type: "completion-message", value: data.message});
+
+ return tokens;
+ };
+ bgTokenizer.$updateOnChange = noop;
+ bgTokenizer.start = noop;
+
+ popup.session.$computeWidth = function() {
+ return this.screenWidth = 0;
+ };
+ popup.isOpen = false;
+ popup.isTopdown = false;
+ popup.autoSelect = true;
+ popup.filterText = "";
+
+ popup.data = [];
+ popup.setData = function(list, filterText) {
+ popup.filterText = filterText || "";
+ popup.setValue(lang.stringRepeat("\n", list.length), -1);
+ popup.data = list || [];
+ popup.setRow(0);
+ };
+ popup.getData = function(row) {
+ return popup.data[row];
+ };
+
+ popup.getRow = function() {
+ return selectionMarker.start.row;
+ };
+ popup.setRow = function(line) {
+ line = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length, line));
+ if (selectionMarker.start.row != line) {
+ popup.selection.clearSelection();
+ selectionMarker.start.row = selectionMarker.end.row = line || 0;
+ popup.session._emit("changeBackMarker");
+ popup.moveCursorTo(line || 0, 0);
+ if (popup.isOpen)
+ popup._signal("select");
+ }
+ };
+
+ popup.on("changeSelection", function() {
+ if (popup.isOpen)
+ popup.setRow(popup.selection.lead.row);
+ popup.renderer.scrollCursorIntoView();
+ });
+
+ popup.hide = function() {
+ this.container.style.display = "none";
+ this._signal("hide");
+ popup.isOpen = false;
+ };
+ popup.show = function(pos, lineHeight, topdownOnly) {
+ var el = this.container;
+ var screenHeight = window.innerHeight;
+ var screenWidth = window.innerWidth;
+ var renderer = this.renderer;
+ var maxH = renderer.$maxLines * lineHeight * 1.4;
+ var top = pos.top + this.$borderSize;
+ var allowTopdown = top > screenHeight / 2 && !topdownOnly;
+ if (allowTopdown && top + lineHeight + maxH > screenHeight) {
+ renderer.$maxPixelHeight = top - 2 * this.$borderSize;
+ el.style.top = "";
+ el.style.bottom = screenHeight - top + "px";
+ popup.isTopdown = false;
+ } else {
+ top += lineHeight;
+ renderer.$maxPixelHeight = screenHeight - top - 0.2 * lineHeight;
+ el.style.top = top + "px";
+ el.style.bottom = "";
+ popup.isTopdown = true;
+ }
+
+ el.style.display = "";
+
+ var left = pos.left;
+ if (left + el.offsetWidth > screenWidth)
+ left = screenWidth - el.offsetWidth;
+
+ el.style.left = left + "px";
+
+ this._signal("show");
+ lastMouseEvent = null;
+ popup.isOpen = true;
+ };
+
+ popup.goTo = function(where) {
+ var row = this.getRow();
+ var max = this.session.getLength() - 1;
+
+ switch(where) {
+ case "up": row = row <= 0 ? max : row - 1; break;
+ case "down": row = row >= max ? -1 : row + 1; break;
+ case "start": row = 0; break;
+ case "end": row = max; break;
+ }
+
+ this.setRow(row);
+ };
+
+
+ popup.getTextLeftOffset = function() {
+ return this.$borderSize + this.renderer.$padding + this.$imageSize;
+ };
+
+ popup.$imageSize = 0;
+ popup.$borderSize = 1;
+
+ return popup;
+};
+
+dom.importCssString("\
+.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\
+ background-color: #CAD6FA;\
+ z-index: 1;\
+}\
+.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\
+ background-color: #3a674e;\
+}\
+.ace_editor.ace_autocomplete .ace_line-hover {\
+ border: 1px solid #abbffe;\
+ margin-top: -1px;\
+ background: rgba(233,233,253,0.4);\
+ position: absolute;\
+ z-index: 2;\
+}\
+.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\
+ border: 1px solid rgba(109, 150, 13, 0.8);\
+ background: rgba(58, 103, 78, 0.62);\
+}\
+.ace_completion-meta {\
+ opacity: 0.5;\
+ margin: 0.9em;\
+}\
+.ace_completion-message {\
+ color: blue;\
+}\
+.ace_editor.ace_autocomplete .ace_completion-highlight{\
+ color: #2d69c7;\
+}\
+.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\
+ color: #93ca12;\
+}\
+.ace_editor.ace_autocomplete {\
+ width: 300px;\
+ z-index: 200000;\
+ border: 1px lightgray solid;\
+ position: fixed;\
+ box-shadow: 2px 3px 5px rgba(0,0,0,.2);\
+ line-height: 1.4;\
+ background: #fefefe;\
+ color: #111;\
+}\
+.ace_dark.ace_editor.ace_autocomplete {\
+ border: 1px #484747 solid;\
+ box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\
+ line-height: 1.4;\
+ background: #25282c;\
+ color: #c1c1c1;\
+}", "autocompletion.css");
+
+exports.AcePopup = AcePopup;
+exports.$singleLineEditor = $singleLineEditor;
+});
+
+define("ace/autocomplete/util",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+exports.parForEach = function(array, fn, callback) {
+ var completed = 0;
+ var arLength = array.length;
+ if (arLength === 0)
+ callback();
+ for (var i = 0; i < arLength; i++) {
+ fn(array[i], function(result, err) {
+ completed++;
+ if (completed === arLength)
+ callback(result, err);
+ });
+ }
+};
+
+var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
+
+exports.retrievePrecedingIdentifier = function(text, pos, regex) {
+ regex = regex || ID_REGEX;
+ var buf = [];
+ for (var i = pos-1; i >= 0; i--) {
+ if (regex.test(text[i]))
+ buf.push(text[i]);
+ else
+ break;
+ }
+ return buf.reverse().join("");
+};
+
+exports.retrieveFollowingIdentifier = function(text, pos, regex) {
+ regex = regex || ID_REGEX;
+ var buf = [];
+ for (var i = pos; i < text.length; i++) {
+ if (regex.test(text[i]))
+ buf.push(text[i]);
+ else
+ break;
+ }
+ return buf;
+};
+
+exports.getCompletionPrefix = function (editor) {
+ var pos = editor.getCursorPosition();
+ var line = editor.session.getLine(pos.row);
+ var prefix;
+ editor.completers.forEach(function(completer) {
+ if (completer.identifierRegexps) {
+ completer.identifierRegexps.forEach(function(identifierRegex) {
+ if (!prefix && identifierRegex)
+ prefix = this.retrievePrecedingIdentifier(line, pos.column, identifierRegex);
+ }.bind(this));
+ }
+ }.bind(this));
+ return prefix || this.retrievePrecedingIdentifier(line, pos.column);
+};
+
+});
+
+define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/lang","ace/lib/dom","ace/snippets","ace/config"], function(require, exports, module) {
+"use strict";
+
+var HashHandler = require("./keyboard/hash_handler").HashHandler;
+var AcePopup = require("./autocomplete/popup").AcePopup;
+var util = require("./autocomplete/util");
+var lang = require("./lib/lang");
+var dom = require("./lib/dom");
+var snippetManager = require("./snippets").snippetManager;
+var config = require("./config");
+
+var Autocomplete = function() {
+ this.autoInsert = false;
+ this.autoSelect = true;
+ this.exactMatch = false;
+ this.gatherCompletionsId = 0;
+ this.keyboardHandler = new HashHandler();
+ this.keyboardHandler.bindKeys(this.commands);
+
+ this.blurListener = this.blurListener.bind(this);
+ this.changeListener = this.changeListener.bind(this);
+ this.mousedownListener = this.mousedownListener.bind(this);
+ this.mousewheelListener = this.mousewheelListener.bind(this);
+
+ this.changeTimer = lang.delayedCall(function() {
+ this.updateCompletions(true);
+ }.bind(this));
+
+ this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);
+};
+
+(function() {
+
+ this.$init = function() {
+ this.popup = new AcePopup(document.body || document.documentElement);
+ this.popup.on("click", function(e) {
+ this.insertMatch();
+ e.stop();
+ }.bind(this));
+ this.popup.focus = this.editor.focus.bind(this.editor);
+ this.popup.on("show", this.tooltipTimer.bind(null, null));
+ this.popup.on("select", this.tooltipTimer.bind(null, null));
+ this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null));
+ return this.popup;
+ };
+
+ this.getPopup = function() {
+ return this.popup || this.$init();
+ };
+
+ this.openPopup = function(editor, prefix, keepPopupPosition) {
+ if (!this.popup)
+ this.$init();
+
+ this.popup.autoSelect = this.autoSelect;
+
+ this.popup.setData(this.completions.filtered, this.completions.filterText);
+
+ editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
+
+ var renderer = editor.renderer;
+ this.popup.setRow(this.autoSelect ? 0 : -1);
+ if (!keepPopupPosition) {
+ this.popup.setTheme(editor.getTheme());
+ this.popup.setFontSize(editor.getFontSize());
+
+ var lineHeight = renderer.layerConfig.lineHeight;
+
+ var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
+ pos.left -= this.popup.getTextLeftOffset();
+
+ var rect = editor.container.getBoundingClientRect();
+ pos.top += rect.top - renderer.layerConfig.offset;
+ pos.left += rect.left - editor.renderer.scrollLeft;
+ pos.left += renderer.gutterWidth;
+
+ this.popup.show(pos, lineHeight);
+ } else if (keepPopupPosition && !prefix) {
+ this.detach();
+ }
+ };
+
+ this.detach = function() {
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
+ this.editor.off("changeSelection", this.changeListener);
+ this.editor.off("blur", this.blurListener);
+ this.editor.off("mousedown", this.mousedownListener);
+ this.editor.off("mousewheel", this.mousewheelListener);
+ this.changeTimer.cancel();
+ this.hideDocTooltip();
+
+ this.gatherCompletionsId += 1;
+ if (this.popup && this.popup.isOpen)
+ this.popup.hide();
+
+ if (this.base)
+ this.base.detach();
+ this.activated = false;
+ this.completions = this.base = null;
+ };
+
+ this.changeListener = function(e) {
+ var cursor = this.editor.selection.lead;
+ if (cursor.row != this.base.row || cursor.column < this.base.column) {
+ this.detach();
+ }
+ if (this.activated)
+ this.changeTimer.schedule();
+ else
+ this.detach();
+ };
+
+ this.blurListener = function(e) {
+ var el = document.activeElement;
+ var text = this.editor.textInput.getElement();
+ var fromTooltip = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget);
+ var container = this.popup && this.popup.container;
+ if (el != text && el.parentNode != container && !fromTooltip
+ && el != this.tooltipNode && e.relatedTarget != text
+ ) {
+ this.detach();
+ }
+ };
+
+ this.mousedownListener = function(e) {
+ this.detach();
+ };
+
+ this.mousewheelListener = function(e) {
+ this.detach();
+ };
+
+ this.goTo = function(where) {
+ this.popup.goTo(where);
+ };
+
+ this.insertMatch = function(data, options) {
+ if (!data)
+ data = this.popup.getData(this.popup.getRow());
+ if (!data)
+ return false;
+
+ if (data.completer && data.completer.insertMatch) {
+ data.completer.insertMatch(this.editor, data);
+ } else {
+ if (this.completions.filterText) {
+ var ranges = this.editor.selection.getAllRanges();
+ for (var i = 0, range; range = ranges[i]; i++) {
+ range.start.column -= this.completions.filterText.length;
+ this.editor.session.remove(range);
+ }
+ }
+ if (data.snippet)
+ snippetManager.insertSnippet(this.editor, data.snippet);
+ else
+ this.editor.execCommand("insertstring", data.value || data);
+ }
+ this.detach();
+ };
+
+
+ this.commands = {
+ "Up": function(editor) { editor.completer.goTo("up"); },
+ "Down": function(editor) { editor.completer.goTo("down"); },
+ "Ctrl-Up|Ctrl-Home": function(editor) { editor.completer.goTo("start"); },
+ "Ctrl-Down|Ctrl-End": function(editor) { editor.completer.goTo("end"); },
+
+ "Esc": function(editor) { editor.completer.detach(); },
+ "Return": function(editor) { return editor.completer.insertMatch(); },
+ "Shift-Return": function(editor) { editor.completer.insertMatch(null, {deleteSuffix: true}); },
+ "Tab": function(editor) {
+ var result = editor.completer.insertMatch();
+ if (!result && !editor.tabstopManager)
+ editor.completer.goTo("down");
+ else
+ return result;
+ },
+
+ "PageUp": function(editor) { editor.completer.popup.gotoPageUp(); },
+ "PageDown": function(editor) { editor.completer.popup.gotoPageDown(); }
+ };
+
+ this.gatherCompletions = function(editor, callback) {
+ var session = editor.getSession();
+ var pos = editor.getCursorPosition();
+
+ var prefix = util.getCompletionPrefix(editor);
+
+ this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
+ this.base.$insertRight = true;
+
+ var matches = [];
+ var total = editor.completers.length;
+ editor.completers.forEach(function(completer, i) {
+ completer.getCompletions(editor, session, pos, prefix, function(err, results) {
+ if (!err && results)
+ matches = matches.concat(results);
+ callback(null, {
+ prefix: util.getCompletionPrefix(editor),
+ matches: matches,
+ finished: (--total === 0)
+ });
+ });
+ });
+ return true;
+ };
+
+ this.showPopup = function(editor, options) {
+ if (this.editor)
+ this.detach();
+
+ this.activated = true;
+
+ this.editor = editor;
+ if (editor.completer != this) {
+ if (editor.completer)
+ editor.completer.detach();
+ editor.completer = this;
+ }
+
+ editor.on("changeSelection", this.changeListener);
+ editor.on("blur", this.blurListener);
+ editor.on("mousedown", this.mousedownListener);
+ editor.on("mousewheel", this.mousewheelListener);
+
+ this.updateCompletions(false, options);
+ };
+
+ this.updateCompletions = function(keepPopupPosition, options) {
+ if (keepPopupPosition && this.base && this.completions) {
+ var pos = this.editor.getCursorPosition();
+ var prefix = this.editor.session.getTextRange({start: this.base, end: pos});
+ if (prefix == this.completions.filterText)
+ return;
+ this.completions.setFilter(prefix);
+ if (!this.completions.filtered.length)
+ return this.detach();
+ if (this.completions.filtered.length == 1
+ && this.completions.filtered[0].value == prefix
+ && !this.completions.filtered[0].snippet)
+ return this.detach();
+ this.openPopup(this.editor, prefix, keepPopupPosition);
+ return;
+ }
+
+ if (options && options.matches) {
+ var pos = this.editor.getSelectionRange().start;
+ this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);
+ this.base.$insertRight = true;
+ this.completions = new FilteredList(options.matches);
+ return this.openPopup(this.editor, "", keepPopupPosition);
+ }
+ var _id = this.gatherCompletionsId;
+ this.gatherCompletions(this.editor, function(err, results) {
+ var detachIfFinished = function() {
+ if (!results.finished) return;
+ return this.detach();
+ }.bind(this);
+
+ var prefix = results.prefix;
+ var matches = results && results.matches;
+
+ if (!matches || !matches.length)
+ return detachIfFinished();
+ if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId)
+ return;
+
+ this.completions = new FilteredList(matches);
+
+ if (this.exactMatch)
+ this.completions.exactMatch = true;
+
+ this.completions.setFilter(prefix);
+ var filtered = this.completions.filtered;
+ if (!filtered.length)
+ return detachIfFinished();
+ if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet)
+ return detachIfFinished();
+ if (this.autoInsert && filtered.length == 1 && results.finished)
+ return this.insertMatch(filtered[0]);
+
+ this.openPopup(this.editor, prefix, keepPopupPosition);
+ }.bind(this));
+ };
+
+ this.cancelContextMenu = function() {
+ this.editor.$mouseHandler.cancelContextMenu();
+ };
+
+ this.updateDocTooltip = function() {
+ var popup = this.popup;
+ var all = popup.data;
+ var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]);
+ var doc = null;
+ if (!selected || !this.editor || !this.popup.isOpen)
+ return this.hideDocTooltip();
+ this.editor.completers.some(function(completer) {
+ if (completer.getDocTooltip)
+ doc = completer.getDocTooltip(selected);
+ return doc;
+ });
+ if (!doc && typeof selected != "string")
+ doc = selected;
+
+ if (typeof doc == "string")
+ doc = {docText: doc};
+ if (!doc || !(doc.docHTML || doc.docText))
+ return this.hideDocTooltip();
+ this.showDocTooltip(doc);
+ };
+
+ this.showDocTooltip = function(item) {
+ if (!this.tooltipNode) {
+ this.tooltipNode = dom.createElement("div");
+ this.tooltipNode.className = "ace_tooltip ace_doc-tooltip";
+ this.tooltipNode.style.margin = 0;
+ this.tooltipNode.style.pointerEvents = "auto";
+ this.tooltipNode.tabIndex = -1;
+ this.tooltipNode.onblur = this.blurListener.bind(this);
+ this.tooltipNode.onclick = this.onTooltipClick.bind(this);
+ }
+
+ var tooltipNode = this.tooltipNode;
+ if (item.docHTML) {
+ tooltipNode.innerHTML = item.docHTML;
+ } else if (item.docText) {
+ tooltipNode.textContent = item.docText;
+ }
+
+ if (!tooltipNode.parentNode)
+ document.body.appendChild(tooltipNode);
+ var popup = this.popup;
+ var rect = popup.container.getBoundingClientRect();
+ tooltipNode.style.top = popup.container.style.top;
+ tooltipNode.style.bottom = popup.container.style.bottom;
+
+ tooltipNode.style.display = "block";
+ if (window.innerWidth - rect.right < 320) {
+ if (rect.left < 320) {
+ if(popup.isTopdown) {
+ tooltipNode.style.top = rect.bottom + "px";
+ tooltipNode.style.left = rect.left + "px";
+ tooltipNode.style.right = "";
+ tooltipNode.style.bottom = "";
+ } else {
+ tooltipNode.style.top = popup.container.offsetTop - tooltipNode.offsetHeight + "px";
+ tooltipNode.style.left = rect.left + "px";
+ tooltipNode.style.right = "";
+ tooltipNode.style.bottom = "";
+ }
+ } else {
+ tooltipNode.style.right = window.innerWidth - rect.left + "px";
+ tooltipNode.style.left = "";
+ }
+ } else {
+ tooltipNode.style.left = (rect.right + 1) + "px";
+ tooltipNode.style.right = "";
+ }
+ };
+
+ this.hideDocTooltip = function() {
+ this.tooltipTimer.cancel();
+ if (!this.tooltipNode) return;
+ var el = this.tooltipNode;
+ if (!this.editor.isFocused() && document.activeElement == el)
+ this.editor.focus();
+ this.tooltipNode = null;
+ if (el.parentNode)
+ el.parentNode.removeChild(el);
+ };
+
+ this.onTooltipClick = function(e) {
+ var a = e.target;
+ while (a && a != this.tooltipNode) {
+ if (a.nodeName == "A" && a.href) {
+ a.rel = "noreferrer";
+ a.target = "_blank";
+ break;
+ }
+ a = a.parentNode;
+ }
+ };
+
+ this.destroy = function() {
+ this.detach();
+ if (this.popup) {
+ this.popup.destroy();
+ var el = this.popup.container;
+ if (el && el.parentNode)
+ el.parentNode.removeChild(el);
+ }
+ if (this.editor && this.editor.completer == this)
+ this.editor.completer == null;
+ this.popup = null;
+ };
+
+}).call(Autocomplete.prototype);
+
+
+Autocomplete.for = function(editor) {
+ if (editor.completer) {
+ return editor.completer;
+ }
+ if (config.get("sharedPopups")) {
+ if (!Autocomplete.$shared)
+ Autocomplete.$sharedInstance = new Autocomplete();
+ editor.completer = Autocomplete.$sharedInstance;
+ } else {
+ editor.completer = new Autocomplete();
+ editor.once("destroy", function(e, editor) {
+ editor.completer.destroy();
+ });
+ }
+ return editor.completer;
+};
+
+Autocomplete.startCommand = {
+ name: "startAutocomplete",
+ exec: function(editor, options) {
+ var completer = Autocomplete.for(editor);
+ completer.autoInsert = false;
+ completer.autoSelect = true;
+ completer.showPopup(editor, options);
+ completer.cancelContextMenu();
+ },
+ bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
+};
+
+var FilteredList = function(array, filterText) {
+ this.all = array;
+ this.filtered = array;
+ this.filterText = filterText || "";
+ this.exactMatch = false;
+};
+(function(){
+ this.setFilter = function(str) {
+ if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)
+ var matches = this.filtered;
+ else
+ var matches = this.all;
+
+ this.filterText = str;
+ matches = this.filterCompletions(matches, this.filterText);
+ matches = matches.sort(function(a, b) {
+ return b.exactMatch - a.exactMatch || b.$score - a.$score
+ || (a.caption || a.value).localeCompare(b.caption || b.value);
+ });
+ var prev = null;
+ matches = matches.filter(function(item){
+ var caption = item.snippet || item.caption || item.value;
+ if (caption === prev) return false;
+ prev = caption;
+ return true;
+ });
+
+ this.filtered = matches;
+ };
+ this.filterCompletions = function(items, needle) {
+ var results = [];
+ var upper = needle.toUpperCase();
+ var lower = needle.toLowerCase();
+ loop: for (var i = 0, item; item = items[i]; i++) {
+ var caption = item.caption || item.value || item.snippet;
+ if (!caption) continue;
+ var lastIndex = -1;
+ var matchMask = 0;
+ var penalty = 0;
+ var index, distance;
+
+ if (this.exactMatch) {
+ if (needle !== caption.substr(0, needle.length))
+ continue loop;
+ } else {
+ var fullMatchIndex = caption.toLowerCase().indexOf(lower);
+ if (fullMatchIndex > -1) {
+ penalty = fullMatchIndex;
+ } else {
+ for (var j = 0; j < needle.length; j++) {
+ var i1 = caption.indexOf(lower[j], lastIndex + 1);
+ var i2 = caption.indexOf(upper[j], lastIndex + 1);
+ index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;
+ if (index < 0)
+ continue loop;
+ distance = index - lastIndex - 1;
+ if (distance > 0) {
+ if (lastIndex === -1)
+ penalty += 10;
+ penalty += distance;
+ matchMask = matchMask | (1 << j);
+ }
+ lastIndex = index;
+ }
+ }
+ }
+ item.matchMask = matchMask;
+ item.exactMatch = penalty ? 0 : 1;
+ item.$score = (item.score || 0) - penalty;
+ results.push(item);
+ }
+ return results;
+ };
+}).call(FilteredList.prototype);
+
+exports.Autocomplete = Autocomplete;
+exports.FilteredList = FilteredList;
+
+});
+
+define("ace/autocomplete/text_completer",["require","exports","module","ace/range"], function(require, exports, module) {
+ var Range = require("../range").Range;
+
+ var splitRegex = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
+
+ function getWordIndex(doc, pos) {
+ var textBefore = doc.getTextRange(Range.fromPoints({row: 0, column:0}, pos));
+ return textBefore.split(splitRegex).length - 1;
+ }
+ function wordDistance(doc, pos) {
+ var prefixPos = getWordIndex(doc, pos);
+ var words = doc.getValue().split(splitRegex);
+ var wordScores = Object.create(null);
+
+ var currentWord = words[prefixPos];
+
+ words.forEach(function(word, idx) {
+ if (!word || word === currentWord) return;
+
+ var distance = Math.abs(prefixPos - idx);
+ var score = words.length - distance;
+ if (wordScores[word]) {
+ wordScores[word] = Math.max(score, wordScores[word]);
+ } else {
+ wordScores[word] = score;
+ }
+ });
+ return wordScores;
+ }
+
+ exports.getCompletions = function(editor, session, pos, prefix, callback) {
+ var wordScore = wordDistance(session, pos);
+ var wordList = Object.keys(wordScore);
+ callback(null, wordList.map(function(word) {
+ return {
+ caption: word,
+ value: word,
+ score: wordScore[word],
+ meta: "local"
+ };
+ }));
+ };
+});
+
+define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/lib/lang","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"], function(require, exports, module) {
+"use strict";
+
+var snippetManager = require("../snippets").snippetManager;
+var Autocomplete = require("../autocomplete").Autocomplete;
+var config = require("../config");
+var lang = require("../lib/lang");
+var util = require("../autocomplete/util");
+
+var textCompleter = require("../autocomplete/text_completer");
+var keyWordCompleter = {
+ getCompletions: function(editor, session, pos, prefix, callback) {
+ if (session.$mode.completer) {
+ return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback);
+ }
+ var state = editor.session.getState(pos.row);
+ var completions = session.$mode.getCompletions(state, session, pos, prefix);
+ callback(null, completions);
+ }
+};
+
+var snippetCompleter = {
+ getCompletions: function(editor, session, pos, prefix, callback) {
+ var scopes = [];
+ var token = session.getTokenAt(pos.row, pos.column);
+ if (token && token.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/))
+ scopes.push('html-tag');
+ else
+ scopes = snippetManager.getActiveScopes(editor);
+
+ var snippetMap = snippetManager.snippetMap;
+ var completions = [];
+ scopes.forEach(function(scope) {
+ var snippets = snippetMap[scope] || [];
+ for (var i = snippets.length; i--;) {
+ var s = snippets[i];
+ var caption = s.name || s.tabTrigger;
+ if (!caption)
+ continue;
+ completions.push({
+ caption: caption,
+ snippet: s.content,
+ meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet",
+ type: "snippet"
+ });
+ }
+ }, this);
+ callback(null, completions);
+ },
+ getDocTooltip: function(item) {
+ if (item.type == "snippet" && !item.docHTML) {
+ item.docHTML = [
+ "", lang.escapeHTML(item.caption), "", "",
+ lang.escapeHTML(item.snippet)
+ ].join("");
+ }
+ }
+};
+
+var completers = [snippetCompleter, textCompleter, keyWordCompleter];
+exports.setCompleters = function(val) {
+ completers.length = 0;
+ if (val) completers.push.apply(completers, val);
+};
+exports.addCompleter = function(completer) {
+ completers.push(completer);
+};
+exports.textCompleter = textCompleter;
+exports.keyWordCompleter = keyWordCompleter;
+exports.snippetCompleter = snippetCompleter;
+
+var expandSnippet = {
+ name: "expandSnippet",
+ exec: function(editor) {
+ return snippetManager.expandWithTab(editor);
+ },
+ bindKey: "Tab"
+};
+
+var onChangeMode = function(e, editor) {
+ loadSnippetsForMode(editor.session.$mode);
+};
+
+var loadSnippetsForMode = function(mode) {
+ var id = mode.$id;
+ if (!snippetManager.files)
+ snippetManager.files = {};
+ loadSnippetFile(id);
+ if (mode.modes)
+ mode.modes.forEach(loadSnippetsForMode);
+};
+
+var loadSnippetFile = function(id) {
+ if (!id || snippetManager.files[id])
+ return;
+ var snippetFilePath = id.replace("mode", "snippets");
+ snippetManager.files[id] = {};
+ config.loadModule(snippetFilePath, function(m) {
+ if (m) {
+ snippetManager.files[id] = m;
+ if (!m.snippets && m.snippetText)
+ m.snippets = snippetManager.parseSnippetFile(m.snippetText);
+ snippetManager.register(m.snippets || [], m.scope);
+ if (m.includeScopes) {
+ snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes;
+ m.includeScopes.forEach(function(x) {
+ loadSnippetFile("ace/mode/" + x);
+ });
+ }
+ }
+ });
+};
+
+var doLiveAutocomplete = function(e) {
+ var editor = e.editor;
+ var hasCompleter = editor.completer && editor.completer.activated;
+ if (e.command.name === "backspace") {
+ if (hasCompleter && !util.getCompletionPrefix(editor))
+ editor.completer.detach();
+ }
+ else if (e.command.name === "insertstring") {
+ var prefix = util.getCompletionPrefix(editor);
+ if (prefix && !hasCompleter) {
+ var completer = Autocomplete.for(editor);
+ completer.autoInsert = false;
+ completer.showPopup(editor);
+ }
+ }
+};
+
+var Editor = require("../editor").Editor;
+require("../config").defineOptions(Editor.prototype, "editor", {
+ enableBasicAutocompletion: {
+ set: function(val) {
+ if (val) {
+ if (!this.completers)
+ this.completers = Array.isArray(val)? val: completers;
+ this.commands.addCommand(Autocomplete.startCommand);
+ } else {
+ this.commands.removeCommand(Autocomplete.startCommand);
+ }
+ },
+ value: false
+ },
+ enableLiveAutocompletion: {
+ set: function(val) {
+ if (val) {
+ if (!this.completers)
+ this.completers = Array.isArray(val)? val: completers;
+ this.commands.on('afterExec', doLiveAutocomplete);
+ } else {
+ this.commands.removeListener('afterExec', doLiveAutocomplete);
+ }
+ },
+ value: false
+ },
+ enableSnippets: {
+ set: function(val) {
+ if (val) {
+ this.commands.addCommand(expandSnippet);
+ this.on("changeMode", onChangeMode);
+ onChangeMode(null, this);
+ } else {
+ this.commands.removeCommand(expandSnippet);
+ this.off("changeMode", onChangeMode);
+ }
+ },
+ value: false
+ }
+});
+});
+
+define("ace/ext/beautify",["require","exports","module","ace/token_iterator"], function(require, exports, module) {
+"use strict";
+var TokenIterator = require("../token_iterator").TokenIterator;
+
+function is(token, type) {
+ return token.type.lastIndexOf(type + ".xml") > -1;
+}
+exports.singletonTags = ["area", "base", "br", "col", "command", "embed", "hr", "html", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"];
+exports.blockTags = ["article", "aside", "blockquote", "body", "div", "dl", "fieldset", "footer", "form", "head", "header", "html", "nav", "ol", "p", "script", "section", "style", "table", "tbody", "tfoot", "thead", "ul"];
+
+exports.beautify = function(session) {
+ var iterator = new TokenIterator(session, 0, 0);
+ var token = iterator.getCurrentToken();
+ var tabString = session.getTabString();
+ var singletonTags = exports.singletonTags;
+ var blockTags = exports.blockTags;
+ var nextToken;
+ var breakBefore = false;
+ var spaceBefore = false;
+ var spaceAfter = false;
+ var code = "";
+ var value = "";
+ var tagName = "";
+ var depth = 0;
+ var lastDepth = 0;
+ var lastIndent = 0;
+ var indent = 0;
+ var unindent = 0;
+ var roundDepth = 0;
+ var curlyDepth = 0;
+ var row;
+ var curRow = 0;
+ var rowsToAdd = 0;
+ var rowTokens = [];
+ var abort = false;
+ var i;
+ var indentNextLine = false;
+ var inTag = false;
+ var inCSS = false;
+ var inBlock = false;
+ var levels = {0: 0};
+ var parents = [];
+
+ var trimNext = function() {
+ if (nextToken && nextToken.value && nextToken.type !== 'string.regexp')
+ nextToken.value = nextToken.value.trim();
+ };
+
+ var trimLine = function() {
+ code = code.replace(/ +$/, "");
+ };
+
+ var trimCode = function() {
+ code = code.trimRight();
+ breakBefore = false;
+ };
+
+ while (token !== null) {
+ curRow = iterator.getCurrentTokenRow();
+ rowTokens = iterator.$rowTokens;
+ nextToken = iterator.stepForward();
+
+ if (typeof token !== "undefined") {
+ value = token.value;
+ unindent = 0;
+ inCSS = (tagName === "style" || session.$modeId === "ace/mode/css");
+ if (is(token, "tag-open")) {
+ inTag = true;
+ if (nextToken)
+ inBlock = (blockTags.indexOf(nextToken.value) !== -1);
+ if (value === "") {
+ if (inBlock && !breakBefore && rowsToAdd < 1)
+ rowsToAdd++;
+
+ if (inCSS)
+ rowsToAdd = 1;
+
+ unindent = 1;
+ inBlock = false;
+ }
+ } else if (is(token, "tag-close")) {
+ inTag = false;
+ } else if (is(token, "comment.start")) {
+ inBlock = true;
+ } else if (is(token, "comment.end")) {
+ inBlock = false;
+ }
+ if (!inTag && !rowsToAdd && token.type === "paren.rparen" && token.value.substr(0, 1) === "}") {
+ rowsToAdd++;
+ }
+ if (curRow !== row) {
+ rowsToAdd = curRow;
+
+ if (row)
+ rowsToAdd -= row;
+ }
+
+ if (rowsToAdd) {
+ trimCode();
+ for (; rowsToAdd > 0; rowsToAdd--)
+ code += "\n";
+
+ breakBefore = true;
+ if (!is(token, "comment") && !token.type.match(/^(comment|string)$/))
+ value = value.trimLeft();
+ }
+
+ if (value) {
+ if (token.type === "keyword" && value.match(/^(if|else|elseif|for|foreach|while|switch)$/)) {
+ parents[depth] = value;
+
+ trimNext();
+ spaceAfter = true;
+ if (value.match(/^(else|elseif)$/)) {
+ if (code.match(/\}[\s]*$/)) {
+ trimCode();
+ spaceBefore = true;
+ }
+ }
+ } else if (token.type === "paren.lparen") {
+ trimNext();
+ if (value.substr(-1) === "{") {
+ spaceAfter = true;
+ indentNextLine = false;
+
+ if(!inTag)
+ rowsToAdd = 1;
+ }
+ if (value.substr(0, 1) === "{") {
+ spaceBefore = true;
+ if (code.substr(-1) !== '[' && code.trimRight().substr(-1) === '[') {
+ trimCode();
+ spaceBefore = false;
+ } else if (code.trimRight().substr(-1) === ')') {
+ trimCode();
+ } else {
+ trimLine();
+ }
+ }
+ } else if (token.type === "paren.rparen") {
+ unindent = 1;
+ if (value.substr(0, 1) === "}") {
+ if (parents[depth-1] === 'case')
+ unindent++;
+
+ if (code.trimRight().substr(-1) === '{') {
+ trimCode();
+ } else {
+ spaceBefore = true;
+
+ if (inCSS)
+ rowsToAdd+=2;
+ }
+ }
+ if (value.substr(0, 1) === "]") {
+ if (code.substr(-1) !== '}' && code.trimRight().substr(-1) === '}') {
+ spaceBefore = false;
+ indent++;
+ trimCode();
+ }
+ }
+ if (value.substr(0, 1) === ")") {
+ if (code.substr(-1) !== '(' && code.trimRight().substr(-1) === '(') {
+ spaceBefore = false;
+ indent++;
+ trimCode();
+ }
+ }
+
+ trimLine();
+ } else if ((token.type === "keyword.operator" || token.type === "keyword") && value.match(/^(=|==|===|!=|!==|&&|\|\||and|or|xor|\+=|.=|>|>=|<|<=|=>)$/)) {
+ trimCode();
+ trimNext();
+ spaceBefore = true;
+ spaceAfter = true;
+ } else if (token.type === "punctuation.operator" && value === ';') {
+ trimCode();
+ trimNext();
+ spaceAfter = true;
+
+ if (inCSS)
+ rowsToAdd++;
+ } else if (token.type === "punctuation.operator" && value.match(/^(:|,)$/)) {
+ trimCode();
+ trimNext();
+ if (value.match(/^(,)$/) && curlyDepth>0 && roundDepth===0) {
+ rowsToAdd++;
+ } else {
+ spaceAfter = true;
+ breakBefore = false;
+ }
+ } else if (token.type === "support.php_tag" && value === "?>" && !breakBefore) {
+ trimCode();
+ spaceBefore = true;
+ } else if (is(token, "attribute-name") && code.substr(-1).match(/^\s$/)) {
+ spaceBefore = true;
+ } else if (is(token, "attribute-equals")) {
+ trimLine();
+ trimNext();
+ } else if (is(token, "tag-close")) {
+ trimLine();
+ if(value === "/>")
+ spaceBefore = true;
+ }
+ if (breakBefore && !(token.type.match(/^(comment)$/) && !value.substr(0, 1).match(/^[/#]$/)) && !(token.type.match(/^(string)$/) && !value.substr(0, 1).match(/^['"]$/))) {
+
+ indent = lastIndent;
+
+ if(depth > lastDepth) {
+ indent++;
+
+ for (i=depth; i > lastDepth; i--)
+ levels[i] = indent;
+ } else if(depth < lastDepth)
+ indent = levels[depth];
+
+ lastDepth = depth;
+ lastIndent = indent;
+
+ if(unindent)
+ indent -= unindent;
+
+ if (indentNextLine && !roundDepth) {
+ indent++;
+ indentNextLine = false;
+ }
+
+ for (i = 0; i < indent; i++)
+ code += tabString;
+ }
+
+
+ if (token.type === "keyword" && value.match(/^(case|default)$/)) {
+ parents[depth] = value;
+ depth++;
+ }
+
+
+ if (token.type === "keyword" && value.match(/^(break)$/)) {
+ if(parents[depth-1] && parents[depth-1].match(/^(case|default)$/)) {
+ depth--;
+ }
+ }
+ if (token.type === "paren.lparen") {
+ roundDepth += (value.match(/\(/g) || []).length;
+ curlyDepth += (value.match(/\{/g) || []).length;
+ depth += value.length;
+ }
+
+ if (token.type === "keyword" && value.match(/^(if|else|elseif|for|while)$/)) {
+ indentNextLine = true;
+ roundDepth = 0;
+ } else if (!roundDepth && value.trim() && token.type !== "comment")
+ indentNextLine = false;
+
+ if (token.type === "paren.rparen") {
+ roundDepth -= (value.match(/\)/g) || []).length;
+ curlyDepth -= (value.match(/\}/g) || []).length;
+
+ for (i = 0; i < value.length; i++) {
+ depth--;
+ if(value.substr(i, 1)==='}' && parents[depth]==='case') {
+ depth--;
+ }
+ }
+ }
+ if (spaceBefore && !breakBefore) {
+ trimLine();
+ if (code.substr(-1) !== "\n")
+ code += " ";
+ }
+
+ code += value;
+
+ if (spaceAfter)
+ code += " ";
+
+ breakBefore = false;
+ spaceBefore = false;
+ spaceAfter = false;
+ if ((is(token, "tag-close") && (inBlock || blockTags.indexOf(tagName) !== -1)) || (is(token, "doctype") && value === ">")) {
+ if (inBlock && nextToken && nextToken.value === "")
+ rowsToAdd = -1;
+ else
+ rowsToAdd = 1;
+ }
+ if (is(token, "tag-open") && value === "") {
+ depth--;
+ } else if (is(token, "tag-open") && value === "<" && singletonTags.indexOf(nextToken.value) === -1) {
+ depth++;
+ } else if (is(token, "tag-name")) {
+ tagName = value;
+ } else if (is(token, "tag-close") && value === "/>" && singletonTags.indexOf(tagName) === -1){
+ depth--;
+ }
+
+ row = curRow;
+ }
+ }
+
+ token = nextToken;
+ }
+
+ code = code.trim();
+ session.doc.setValue(code);
+};
+
+exports.commands = [{
+ name: "beautify",
+ description: "Format selection (Beautify)",
+ exec: function(editor) {
+ exports.beautify(editor.session);
+ },
+ bindKey: "Ctrl-Shift-B"
+}];
+
+});
+
+define("kitchen-sink/demo",["require","exports","module","ace/lib/fixoldbrowsers","ace/ext/rtl","ace/multi_select","kitchen-sink/inline_editor","kitchen-sink/dev_util","kitchen-sink/file_drop","ace/config","ace/lib/dom","ace/lib/net","ace/lib/lang","ace/lib/useragent","ace/lib/event","ace/theme/textmate","ace/edit_session","ace/undomanager","ace/keyboard/hash_handler","ace/virtual_renderer","ace/editor","ace/ext/whitespace","kitchen-sink/doclist","kitchen-sink/layout","kitchen-sink/util","ace/ext/elastic_tabstops_lite","ace/incremental_search","kitchen-sink/token_tooltip","ace/config","ace/worker/worker_client","ace/split","ace/ext/options","ace/ext/statusbar","ace/ext/emmet","ace/placeholder","ace/snippets","ace/ext/language_tools","ace/ext/beautify","ace/keyboard/keybinding","ace/commands/command_manager"], function(require, exports, module) {
+"use strict";
+
+require("ace/lib/fixoldbrowsers");
+
+require("ace/ext/rtl");
+
+require("ace/multi_select");
+require("./inline_editor");
+var devUtil = require("./dev_util");
+require("./file_drop");
+
+var config = require("ace/config");
+config.init();
+var env = {};
+
+var dom = require("ace/lib/dom");
+var net = require("ace/lib/net");
+var lang = require("ace/lib/lang");
+var useragent = require("ace/lib/useragent");
+
+var event = require("ace/lib/event");
+var theme = require("ace/theme/textmate");
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+
+var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
+
+var Renderer = require("ace/virtual_renderer").VirtualRenderer;
+var Editor = require("ace/editor").Editor;
+
+var whitespace = require("ace/ext/whitespace");
+
+
+
+var doclist = require("./doclist");
+var layout = require("./layout");
+var util = require("./util");
+var saveOption = util.saveOption;
+
+
+var ElasticTabstopsLite = require("ace/ext/elastic_tabstops_lite").ElasticTabstopsLite;
+
+var IncrementalSearch = require("ace/incremental_search").IncrementalSearch;
+
+
+var TokenTooltip = require("./token_tooltip").TokenTooltip;
+require("ace/config").defineOptions(Editor.prototype, "editor", {
+ showTokenInfo: {
+ set: function(val) {
+ if (val) {
+ this.tokenTooltip = this.tokenTooltip || new TokenTooltip(this);
+ }
+ else if (this.tokenTooltip) {
+ this.tokenTooltip.destroy();
+ delete this.tokenTooltip;
+ }
+ },
+ get: function() {
+ return !!this.tokenTooltip;
+ },
+ handlesSet: true
+ }
+});
+
+
+var workerModule = require("ace/worker/worker_client");
+if (location.href.indexOf("noworker") !== -1) {
+ workerModule.WorkerClient = workerModule.UIWorkerClient;
+}
+var container = document.getElementById("editor-container");
+var Split = require("ace/split").Split;
+var split = new Split(container, theme, 1);
+env.editor = split.getEditor(0);
+split.on("focus", function(editor) {
+ env.editor = editor;
+ updateUIEditorOptions();
+});
+env.split = split;
+window.env = env;
+
+
+var consoleEl = dom.createElement("div");
+container.parentNode.appendChild(consoleEl);
+consoleEl.style.cssText = "position:fixed; bottom:1px; right:0;\
+border:1px solid #baf; z-index:100";
+
+var cmdLine = new layout.singleLineEditor(consoleEl);
+cmdLine.setOption("placeholder", "Enter a command...");
+cmdLine.editor = env.editor;
+env.editor.cmdLine = cmdLine;
+
+env.editor.showCommandLine = function(val) {
+ this.cmdLine.focus();
+ if (typeof val == "string")
+ this.cmdLine.setValue(val, 1);
+};
+env.editor.commands.addCommands([{
+ name: "snippet",
+ bindKey: {win: "Alt-C", mac: "Command-Alt-C"},
+ exec: function(editor, needle) {
+ if (typeof needle == "object") {
+ editor.cmdLine.setValue("snippet ", 1);
+ editor.cmdLine.focus();
+ return;
+ }
+ var s = snippetManager.getSnippetByName(needle, editor);
+ if (s)
+ snippetManager.insertSnippet(editor, s.content);
+ },
+ readOnly: true
+}, {
+ name: "focusCommandLine",
+ bindKey: "shift-esc|ctrl-`",
+ exec: function(editor, needle) { editor.cmdLine.focus(); },
+ readOnly: true
+}, {
+ name: "nextFile",
+ bindKey: "Ctrl-tab",
+ exec: function(editor) { doclist.cycleOpen(editor, 1); },
+ readOnly: true
+}, {
+ name: "previousFile",
+ bindKey: "Ctrl-shift-tab",
+ exec: function(editor) { doclist.cycleOpen(editor, -1); },
+ readOnly: true
+}, {
+ name: "execute",
+ bindKey: "ctrl+enter",
+ exec: function(editor) {
+ try {
+ var r = window.eval(editor.getCopyText() || editor.getValue());
+ } catch(e) {
+ r = e;
+ }
+ editor.cmdLine.setValue(r + "");
+ },
+ readOnly: true
+}, {
+ name: "showKeyboardShortcuts",
+ bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"},
+ exec: function(editor) {
+ config.loadModule("ace/ext/keybinding_menu", function(module) {
+ module.init(editor);
+ editor.showKeyboardShortcuts();
+ });
+ }
+}, {
+ name: "increaseFontSize",
+ bindKey: "Ctrl-=|Ctrl-+",
+ exec: function(editor) {
+ var size = parseInt(editor.getFontSize(), 10) || 12;
+ editor.setFontSize(size + 1);
+ }
+}, {
+ name: "decreaseFontSize",
+ bindKey: "Ctrl+-|Ctrl-_",
+ exec: function(editor) {
+ var size = parseInt(editor.getFontSize(), 10) || 12;
+ editor.setFontSize(Math.max(size - 1 || 1));
+ }
+}, {
+ name: "resetFontSize",
+ bindKey: "Ctrl+0|Ctrl-Numpad0",
+ exec: function(editor) {
+ editor.setFontSize(12);
+ }
+}]);
+
+
+env.editor.commands.addCommands(whitespace.commands);
+
+cmdLine.commands.bindKeys({
+ "Shift-Return|Ctrl-Return|Alt-Return": function(cmdLine) { cmdLine.insert("\n"); },
+ "Esc|Shift-Esc": function(cmdLine){ cmdLine.editor.focus(); },
+ "Return": function(cmdLine){
+ var command = cmdLine.getValue().split(/\s+/);
+ var editor = cmdLine.editor;
+ editor.commands.exec(command[0], editor, command[1]);
+ editor.focus();
+ }
+});
+
+cmdLine.commands.removeCommands(["find", "gotoline", "findall", "replace", "replaceall"]);
+
+var commands = env.editor.commands;
+commands.addCommand({
+ name: "save",
+ bindKey: {win: "Ctrl-S", mac: "Command-S"},
+ exec: function(arg) {
+ var session = env.editor.session;
+ var name = session.name.match(/[^\/]+$/);
+ localStorage.setItem(
+ "saved_file:" + name,
+ session.getValue()
+ );
+ env.editor.cmdLine.setValue("saved "+ name);
+ }
+});
+
+commands.addCommand({
+ name: "load",
+ bindKey: {win: "Ctrl-O", mac: "Command-O"},
+ exec: function(arg) {
+ var session = env.editor.session;
+ var name = session.name.match(/[^\/]+$/);
+ var value = localStorage.getItem("saved_file:" + name);
+ if (typeof value == "string") {
+ session.setValue(value);
+ env.editor.cmdLine.setValue("loaded "+ name);
+ } else {
+ env.editor.cmdLine.setValue("no previuos value saved for "+ name);
+ }
+ }
+});
+var sidePanelContainer = document.getElementById("sidePanel");
+sidePanelContainer.onclick = function(e) {
+ if (dom.hasCssClass(sidePanelContainer, "closed"))
+ onResize(null, false);
+ else if (dom.hasCssClass(e.target, "toggleButton"))
+ onResize(null, true);
+}
+var consoleHeight = 20;
+function onResize(e, closeSidePanel) {
+ var left = 280;
+ var width = document.documentElement.clientWidth;
+ var height = document.documentElement.clientHeight;
+ if (closeSidePanel == null)
+ closeSidePanel = width < 2 * left;
+ if (closeSidePanel)
+ left = 20;
+ width -= left;
+ container.style.width = width + "px";
+ container.style.height = height - consoleHeight + "px";
+ container.style.left = left + "px";
+ env.split.resize();
+
+ consoleEl.style.width = width + "px";
+ consoleEl.style.left = left + "px";
+ cmdLine.resize();
+
+ sidePanel.style.width = left + "px";
+ sidePanel.style.height = height + "px";
+ dom.setCssClass(sidePanelContainer, "closed", closeSidePanel);
+}
+
+window.onresize = onResize;
+onResize();
+doclist.history = doclist.docs.map(function(doc) {
+ return doc.name;
+});
+doclist.history.index = 0;
+doclist.cycleOpen = function(editor, dir) {
+ var h = this.history;
+ h.index += dir;
+ if (h.index >= h.length)
+ h.index = 0;
+ else if (h.index <= 0)
+ h.index = h.length - 1;
+ var s = h[h.index];
+ doclist.pickDocument(s);
+};
+doclist.addToHistory = function(name) {
+ var h = this.history;
+ var i = h.indexOf(name);
+ if (i != h.index) {
+ if (i != -1)
+ h.splice(i, 1);
+ h.index = h.push(name);
+ }
+};
+doclist.pickDocument = function(name) {
+ doclist.loadDoc(name, function(session) {
+ if (!session)
+ return;
+ doclist.addToHistory(session.name);
+ session = env.split.setSession(session);
+ whitespace.detectIndentation(session);
+ optionsPanel.render();
+ env.editor.focus();
+ });
+};
+
+
+
+var OptionPanel = require("ace/ext/options").OptionPanel;
+var optionsPanel = new OptionPanel(env.editor);
+
+optionsPanel.add({
+ Main: {
+ Document: {
+ type: "select",
+ path: "doc",
+ items: doclist.all,
+ position: -101,
+ onchange: doclist.pickDocument,
+ getValue: function() {
+ return env.editor.session.name || "javascript";
+ }
+ },
+ Split: {
+ type: "buttonBar",
+ path: "split",
+ values: ["None", "Below", "Beside"],
+ position: -100,
+ onchange: function(value) {
+ var sp = env.split;
+ if (value == "Below" || value == "Beside") {
+ var newEditor = (sp.getSplits() == 1);
+ sp.setOrientation(value == "Below" ? sp.BELOW : sp.BESIDE);
+ sp.setSplits(2);
+
+ if (newEditor) {
+ var session = sp.getEditor(0).session;
+ var newSession = sp.setSession(session, 1);
+ newSession.name = session.name;
+ }
+ } else {
+ sp.setSplits(1);
+ }
+ },
+ getValue: function() {
+ var sp = env.split;
+ return sp.getSplits() == 1
+ ? "None"
+ : sp.getOrientation() == sp.BELOW
+ ? "Below"
+ : "Beside";
+ }
+ }
+ },
+ More: {
+ "RTL": {
+ path: "rtl",
+ position: 900
+ },
+ "Line based RTL switching": {
+ path: "rtlText",
+ position: 900
+ },
+ "Show token info": {
+ path: "showTokenInfo",
+ position: 2000
+ },
+ "Show Textarea Position": devUtil.textPositionDebugger,
+ "Text Input Debugger": devUtil.textInputDebugger,
+ }
+});
+
+var optionsPanelContainer = document.getElementById("optionsPanel");
+optionsPanel.render();
+optionsPanelContainer.insertBefore(optionsPanel.container, optionsPanelContainer.firstChild);
+optionsPanel.on("setOption", function(e) {
+ util.saveOption(e.name, e.value);
+});
+
+function updateUIEditorOptions() {
+ optionsPanel.editor = env.editor;
+ optionsPanel.render();
+}
+
+optionsPanel.setOption("doc", util.getOption("doc") || "JavaScript");
+for (var i in optionsPanel.options) {
+ var value = util.getOption(i);
+ if (value != undefined) {
+ if ((i == "mode" || i == "theme") && !/[/]/.test(value))
+ value = "ace/" + i + "/" + value;
+ optionsPanel.setOption(i, value);
+ }
+}
+
+
+function synchroniseScrolling() {
+ var s1 = env.split.$editors[0].session;
+ var s2 = env.split.$editors[1].session;
+ s1.on('changeScrollTop', function(pos) {s2.setScrollTop(pos)});
+ s2.on('changeScrollTop', function(pos) {s1.setScrollTop(pos)});
+ s1.on('changeScrollLeft', function(pos) {s2.setScrollLeft(pos)});
+ s2.on('changeScrollLeft', function(pos) {s1.setScrollLeft(pos)});
+}
+
+var StatusBar = require("ace/ext/statusbar").StatusBar;
+new StatusBar(env.editor, cmdLine.container);
+
+
+var Emmet = require("ace/ext/emmet");
+net.loadScript("https://cloud9ide.github.io/emmet-core/emmet.js", function() {
+ Emmet.setCore(window.emmet);
+ env.editor.setOption("enableEmmet", true);
+});
+
+require("ace/placeholder").PlaceHolder;
+
+var snippetManager = require("ace/snippets").snippetManager;
+
+env.editSnippets = function() {
+ var sp = env.split;
+ if (sp.getSplits() == 2) {
+ sp.setSplits(1);
+ return;
+ }
+ sp.setSplits(1);
+ sp.setSplits(2);
+ sp.setOrientation(sp.BESIDE);
+ var editor = sp.$editors[1];
+ var id = sp.$editors[0].session.$mode.$id || "";
+ var m = snippetManager.files[id];
+ if (!doclist["snippets/" + id]) {
+ var text = m.snippetText;
+ var s = doclist.initDoc(text, "", {});
+ s.setMode("ace/mode/snippets");
+ doclist["snippets/" + id] = s;
+ }
+ editor.on("blur", function() {
+ m.snippetText = editor.getValue();
+ snippetManager.unregister(m.snippets);
+ m.snippets = snippetManager.parseSnippetFile(m.snippetText, m.scope);
+ snippetManager.register(m.snippets);
+ });
+ sp.$editors[0].once("changeMode", function() {
+ sp.setSplits(1);
+ });
+ editor.setSession(doclist["snippets/" + id], 1);
+ editor.focus();
+};
+
+optionsPanelContainer.insertBefore(
+ dom.buildDom(["div", {style: "text-align:right;margin-right: 60px"},
+ ["div", {},
+ ["button", {onclick: env.editSnippets}, "Edit Snippets"]],
+ ["div", {},
+ ["button", {onclick: function() {
+ var info = navigator.platform + "\n" + navigator.userAgent;
+ if (env.editor.getValue() == info)
+ return env.editor.undo();
+ env.editor.setValue(info, -1);
+ env.editor.setOption("wrap", 80);
+ }}, "Show Browser Info"]],
+ devUtil.getUI()
+ ]),
+ optionsPanelContainer.children[1]
+);
+
+require("ace/ext/language_tools");
+env.editor.setOptions({
+ enableBasicAutocompletion: true,
+ enableSnippets: true
+});
+
+var beautify = require("ace/ext/beautify");
+env.editor.commands.addCommands(beautify.commands);
+
+var KeyBinding = require("ace/keyboard/keybinding").KeyBinding;
+var CommandManager = require("ace/commands/command_manager").CommandManager;
+var commandManager = new CommandManager();
+var kb = new KeyBinding({
+ commands: commandManager,
+ fake: true
+});
+event.addCommandKeyListener(document.documentElement, kb.onCommandKey.bind(kb));
+event.addListener(document.documentElement, "keyup", function(e) {
+ if (e.keyCode === 18) // do not trigger browser menu on windows
+ e.preventDefault();
+});
+commandManager.addCommands([{
+ name: "window-left",
+ bindKey: {win: "cmd-alt-left", mac: "ctrl-cmd-left"},
+ exec: function() {
+ moveFocus();
+ }
+}, {
+ name: "window-right",
+ bindKey: {win: "cmd-alt-right", mac: "ctrl-cmd-right"},
+ exec: function() {
+ moveFocus();
+ }
+}, {
+ name: "window-up",
+ bindKey: {win: "cmd-alt-up", mac: "ctrl-cmd-up"},
+ exec: function() {
+ moveFocus();
+ }
+}, {
+ name: "window-down",
+ bindKey: {win: "cmd-alt-down", mac: "ctrl-cmd-down"},
+ exec: function() {
+ moveFocus();
+ }
+}]);
+
+function moveFocus() {
+ var el = document.activeElement;
+ if (el == env.editor.textInput.getElement())
+ env.editor.cmdLine.focus();
+ else
+ env.editor.focus();
+}
+
+}); (function() {
+ window.require(["kitchen-sink/demo"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/.gitignore b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/.gitignore
new file mode 100644
index 0000000..56ec8fd
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/.gitignore
@@ -0,0 +1,11 @@
+# A sample .gitignore file.
+
+.buildlog
+.DS_Store
+.svn
+
+# Negated patterns:
+!foo.bar
+
+# Also ignore user settings...
+/.settings
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Dockerfile b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Dockerfile
new file mode 100644
index 0000000..70270cb
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Dockerfile
@@ -0,0 +1,53 @@
+#
+# example Dockerfile for http://docs.docker.io/en/latest/examples/postgresql_service/
+#
+
+FROM ubuntu
+MAINTAINER SvenDowideit@docker.com
+
+# Add the PostgreSQL PGP key to verify their Debian packages.
+# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc
+RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
+
+# Add PostgreSQL's repository. It contains the most recent stable release
+# of PostgreSQL, ``9.3``.
+RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
+
+# Update the Ubuntu and PostgreSQL repository indexes
+RUN apt-get update
+
+# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3
+# There are some warnings (in red) that show up during the build. You can hide
+# them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
+RUN apt-get -y -q install python-software-properties software-properties-common
+RUN apt-get -y -q install postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
+
+# Note: The official Debian and Ubuntu images automatically ``apt-get clean``
+# after each ``apt-get``
+
+# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``
+USER postgres
+
+# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and
+# then create a database `docker` owned by the ``docker`` role.
+# Note: here we use ``&&\`` to run commands one after the other - the ``\``
+# allows the RUN command to span multiple lines.
+RUN /etc/init.d/postgresql start &&\
+ psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
+ createdb -O docker docker
+
+# Adjust PostgreSQL configuration so that remote connections to the
+# database are possible.
+RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf
+
+# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``
+RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
+
+# Expose the PostgreSQL port
+EXPOSE 5432
+
+# Add VOLUMEs to allow backup of config, logs and databases
+VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
+
+# Set the default command to run when starting the container
+CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Haxe.hx b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Haxe.hx
new file mode 100644
index 0000000..ab205bb
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Haxe.hx
@@ -0,0 +1,17 @@
+class Haxe
+{
+ public static function main()
+ {
+ // Say Hello!
+ var greeting:String = "Hello World";
+ trace(greeting);
+
+ var targets:Array = ["Flash","Javascript","PHP","Neko","C++","iOS","Android","webOS"];
+ trace("Haxe is a great language that can target:");
+ for (target in targets)
+ {
+ trace (" - " + target);
+ }
+ trace("And many more!");
+ }
+}
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Jack.jack b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Jack.jack
new file mode 100644
index 0000000..15acf74
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Jack.jack
@@ -0,0 +1,247 @@
+vars it, p
+
+p = {label, value|
+ print("\n" + label)
+ print(inspect(value))
+}
+-- Create an array from 0 to 15
+p("range", i-collect(range(5)))
+
+-- Create an array from 0 to 15 and break up in chunks of 4
+p("chunked range", i-collect(i-chunk(4, range(16))))
+
+-- Check if all or none items in stream pass test.
+p("all < 60 in range(60)", i-all?({i|i<60}, range(60)))
+p("any < 60 in range(60)", i-any?({i|i>60}, range(60)))
+p("all < 60 in range(70)", i-all?({i|i<60}, range(70)))
+p("any < 60 in range(70)", i-any?({i|i>60}, range(70)))
+
+-- Zip three different collections together
+p("zipped", i-collect(i-zip(
+ range(10),
+ [1,2,3,4,5],
+ i-map({i|i*i}, range(10))
+)))
+
+vars names, person, i, doubles, lengths, cubeRange
+names = ["Thorin", "Dwalin", "Balin", "Bifur", "Bofur", "Bombur", "Oin",
+ "Gloin", "Ori", "Nori", "Dori", "Fili", "Kili", "Bilbo", "Gandalf"]
+
+for name in names {
+ if name != "Bilbo" && name != "Gandalf" {
+ print(name)
+ }
+}
+
+person = {name: "Tim", age: 30}
+for key, value in person {
+ print(key + " = " + value)
+}
+
+i = 0
+while i < 10 {
+ i = i + 1
+ print(i)
+}
+
+print("range")
+for i in range(10) {
+ print(i + 1)
+}
+for i in range(10) {
+ print(10 - i)
+}
+
+-- Dynamic object that gives the first 10 doubles
+doubles = {
+ @len: {| 10 }
+ @get: {key|
+ if key is Integer { key * key }
+ }
+}
+print("#doubles", #doubles)
+
+print("Doubles")
+for k, v in doubles {
+ print([k, v])
+}
+
+-- Dynamic object that has names list as keys and string lenth as values
+lengths = {
+ @keys: {| names }
+ @get: {key|
+ if key is String { #key }
+ }
+}
+
+print ("Lengths")
+for k, v in lengths {
+ print([k, v])
+}
+
+
+cubeRange = {n|
+ vars i, v
+ i = 0
+ {
+ @call: {|
+ v = i
+ i = i + 1
+ if v < n { v * v * v }
+ }
+ }
+}
+
+print("Cubes")
+for k, v in cubeRange(5) {
+ print([k, v])
+}
+print("String")
+for k, v in "Hello World" {
+ print([k, v])
+}
+
+
+print([i for i in range(10)])
+print([i for i in range(20) if i % 3])
+
+
+
+-- Example showing how to do parallel work using split..and
+base = {bootstrap, target-dir|
+ split {
+ copy("res", target-dir)
+ } and {
+ if newer("src/*.less", target-dir + "/style.css") {
+ lessc("src/" + bootstrap + ".less", target-dir + "/style.css")
+ }
+ } and {
+ build("src/" + bootstrap + ".js", target-dir + "/app.js")
+ }
+}
+
+
+vars Dragon, pet
+
+Dragon = {name|
+ vars asleep, stuff-in-belly, stuff-in-intestine,
+ feed, walk, put-to-bed, toss, rock,
+ hungry?, poopy?, passage-of-time
+
+ asleep = false
+ stuff-in-belly = 10 -- He's full.
+ stuff-in-intestine = 0 -- He doesn't need to go.
+
+ print(name + ' is born.')
+
+ feed = {|
+ print('You feed ' + name + '.')
+ stuff-in-belly = 10
+ passage-of-time()
+ }
+
+ walk = {|
+ print('You walk ' + name + ".")
+ stuff-in-intestine = 0
+ passage-of-time
+ }
+
+ put-to-bed = {|
+ print('You put ' + name + ' to bed.')
+ asleep = true
+ for i in range(3) {
+ if asleep {
+ passage-of-time()
+ }
+ if asleep {
+ print(name + ' snores, filling the room with smoke.')
+ }
+ }
+ if asleep {
+ asleep = false
+ print(name + ' wakes up slowly.')
+ }
+ }
+
+ toss = {|
+ print('You toss ' + name + ' up into the air.')
+ print('He giggles, which singes your eyebrows.')
+ passage-of-time()
+ }
+
+ rock = {|
+ print('You rock ' + name + ' gently.')
+ asleep = true
+ print('He briefly dozes off...')
+ passage-of-time()
+ if asleep {
+ asleep = false
+ print('...but wakes when you stop.')
+ }
+ }
+
+ hungry? = {|
+ stuff-in-belly <= 2
+ }
+
+ poopy? = {|
+ stuff-in-intestine >= 8
+ }
+
+ passage-of-time = {|
+ if stuff-in-belly > 0 {
+ -- Move food from belly to intestine
+ stuff-in-belly = stuff-in-belly - 1
+ stuff-in-intestine = stuff-in-intestine + 1
+ } else { -- Our dragon is starving!
+ if asleep {
+ asleep = false
+ print('He wakes up suddenly!')
+ }
+ print(name + ' is starving! In desperation, he ate YOU!')
+ abort "died"
+ }
+
+ if stuff-in-intestine >= 10 {
+ stuff-in-intestine = 0
+ print('Whoops! ' + name + ' had an accident...')
+ }
+
+ if hungry?() {
+ if asleep {
+ asleep = false
+ print('He wakes up suddenly!')
+ }
+ print(name + "'s stomach grumbles...")
+ }
+
+ if poopy?() {
+ if asleep {
+ asleep = false
+ print('He wakes up suddenly!')
+ }
+ print(name + ' does the potty dance...')
+ }
+ }
+
+ -- Export the public interface to this closure object.
+ {
+ feed: feed
+ walk: walk
+ put-to-bed: put-to-bed
+ toss: toss
+ rock: rock
+ }
+
+}
+
+pet = Dragon('Norbert')
+pet.feed()
+pet.toss()
+pet.walk()
+pet.put-to-bed()
+pet.rock()
+pet.put-to-bed()
+pet.put-to-bed()
+pet.put-to-bed()
+pet.put-to-bed()
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Makefile b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Makefile
new file mode 100644
index 0000000..9b0b31a
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Makefile
@@ -0,0 +1,122 @@
+.PHONY: apf ext worker mode theme package test
+
+default: apf worker
+
+update: worker
+
+# packages apf
+
+# This is the first line of a comment \
+and this is still part of the comment \
+as is this, since I keep ending each line \
+with a backslash character
+
+apf:
+ cd node_modules/packager; node package.js projects/apf_cloud9.apr
+ cd node_modules/packager; cat build/apf_release.js | sed 's/\(\/\*FILEHEAD(\).*//g' > ../../plugins-client/lib.apf/www/apf-packaged/apf_release.js
+
+# package debug version of apf
+apfdebug:
+ cd node_modules/packager/projects; cat apf_cloud9.apr | sed 's///g' > apf_cloud9_debug2.apr
+ cd node_modules/packager/projects; cat apf_cloud9_debug2.apr | sed 's/apf_release/apf_debug/g' > apf_cloud9_debug.apr; rm apf_cloud9_debug2.apr
+ cd node_modules/packager; node package.js projects/apf_cloud9_debug.apr
+ cd node_modules/packager; cat build/apf_debug.js | sed 's/\(\/\*FILEHEAD(\).*\/apf\/\(.*\)/\1\2/g' > ../../plugins-client/lib.apf/www/apf-packaged/apf_debug.js
+
+# package_apf--temporary fix for non-workering infra
+pack_apf:
+ mkdir -p build/src
+ mv plugins-client/lib.apf/www/apf-packaged/apf_release.js build/src/apf_release.js
+ node build/r.js -o name=./build/src/apf_release.js out=./plugins-client/lib.apf/www/apf-packaged/apf_release.js baseUrl=.
+
+# makes ace; at the moment, requires dryice@0.4.2
+ace:
+ cd node_modules/ace; make clean pre_build; ./Makefile.dryice.js minimal
+
+
+# packages core
+core: ace
+ mkdir -p build/src
+ node build/r.js -o build/core.build.js
+
+# generates packed template
+helper:
+ node build/packed_helper.js
+
+helper_clean:
+ mkdir -p build/src
+ node build/packed_helper.js 1
+
+# packages ext
+ext:
+ node build/r.js -o build/app.build.js
+
+# calls dryice on worker & packages it
+worker: plugins-client/lib.ace/www/worker/worker-language.js
+
+plugins-client/lib.ace/www/worker/worker-language.js plugins-client/lib.ace/www/worker/worker-javascript.js : \
+ $(wildcard node_modules/ace/*) $(wildcard node_modules/ace/*/*) $(wildcard node_modules/ace/*/*/mode/*) \
+ $(wildcard plugins-client/ext.language/*) \
+ $(wildcard plugins-client/ext.language/*/*) \
+ $(wildcard plugins-client/ext.linereport/*) \
+ $(wildcard plugins-client/ext.codecomplete/*) \
+ $(wildcard plugins-client/ext.codecomplete/*/*) \
+ $(wildcard plugins-client/ext.jslanguage/*) \
+ $(wildcard plugins-client/ext.jslanguage/*/*) \
+ $(wildcard plugins-client/ext.csslanguage/*) \
+ $(wildcard plugins-client/ext.csslanguage/*/*) \
+ $(wildcard plugins-client/ext.htmllanguage/*) \
+ $(wildcard plugins-client/ext.htmllanguage/*/*) \
+ $(wildcard plugins-client/ext.jsinfer/*) \
+ $(wildcard plugins-client/ext.jsinfer/*/*) \
+ $(wildcard node_modules/treehugger/lib/*) \
+ $(wildcard node_modules/treehugger/lib/*/*) \
+ $(wildcard node_modules/ace/lib/*) \
+ $(wildcard node_modules/ace/*/*) \
+ Makefile.dryice.js
+ mkdir -p plugins-client/lib.ace/www/worker
+ rm -rf /tmp/c9_worker_build
+ mkdir -p /tmp/c9_worker_build/ext
+ ln -s `pwd`/plugins-client/ext.language /tmp/c9_worker_build/ext/language
+ ln -s `pwd`/plugins-client/ext.codecomplete /tmp/c9_worker_build/ext/codecomplete
+ ln -s `pwd`/plugins-client/ext.jslanguage /tmp/c9_worker_build/ext/jslanguage
+ ln -s `pwd`/plugins-client/ext.csslanguage /tmp/c9_worker_build/ext/csslanguage
+ ln -s `pwd`/plugins-client/ext.htmllanguage /tmp/c9_worker_build/ext/htmllanguage
+ ln -s `pwd`/plugins-client/ext.linereport /tmp/c9_worker_build/ext/linereport
+ ln -s `pwd`/plugins-client/ext.linereport_php /tmp/c9_worker_build/ext/linereport_php
+ node Makefile.dryice.js worker
+ cp node_modules/ace/build/src/worker* plugins-client/lib.ace/www/worker
+
+define
+
+ifeq
+
+override
+
+# copies built ace modes
+mode:
+ mkdir -p plugins-client/lib.ace/www/mode
+ cp `find node_modules/ace/build/src | grep -E "mode-[a-zA-Z_0-9]+.js"` plugins-client/lib.ace/www/mode
+
+# copies built ace themes
+theme:
+ mkdir -p plugins-client/lib.ace/www/theme
+ cp `find node_modules/ace/build/src | grep -E "theme-[a-zA-Z_0-9]+.js"` plugins-client/lib.ace/www/theme
+
+gzip_safe:
+ for i in `ls ./plugins-client/lib.packed/www/*.js`; do \
+ gzip -9 -v -c -q -f $$i > $$i.gz ; \
+ done
+
+gzip:
+ for i in `ls ./plugins-client/lib.packed/www/*.js`; do \
+ gzip -9 -v -q -f $$i ; \
+ done
+
+c9core: apf ace core worker mode theme
+
+package_clean: helper_clean c9core ext
+
+package: helper c9core ext
+
+test check:
+ test/run-tests.sh
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Nix.nix b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Nix.nix
new file mode 100644
index 0000000..9476db3
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/Nix.nix
@@ -0,0 +1,57 @@
+{
+ # Name of our deployment
+ network.description = "HelloWorld";
+ # Enable rolling back to previous versions of our infrastructure
+ network.enableRollback = true;
+
+ # It consists of a single server named 'helloserver'
+ helloserver =
+ # Every server gets passed a few arguments, including a reference
+ # to nixpkgs (pkgs)
+ { config, pkgs, ... }:
+ let
+ # We import our custom packages from ./default passing pkgs as argument
+ packages = import ./default.nix { pkgs = pkgs; };
+ # This is the nodejs version specified in default.nix
+ nodejs = packages.nodejs;
+ # And this is the application we'd like to deploy
+ app = packages.app;
+ in
+ {
+ # We'll be running our application on port 8080, because a regular
+ # user cannot bind to port 80
+ # Then, using some iptables magic we'll forward traffic designated to port 80 to 8080
+ networking.firewall.enable = true;
+ # We will open up port 22 (SSH) as well otherwise we're locking ourselves out
+ networking.firewall.allowedTCPPorts = [ 80 8080 22 ];
+ networking.firewall.allowPing = true;
+
+ # Port forwarding using iptables
+ networking.firewall.extraCommands = ''
+ iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
+ '';
+
+ # To run our node.js program we're going to use a systemd service
+ # We can configure the service to automatically start on boot and to restart
+ # the process in case it crashes
+ systemd.services.helloserver = {
+ description = "Hello world application";
+ # Start the service after the network is available
+ after = [ "network.target" ];
+ # We're going to run it on port 8080 in production
+ environment = { PORT = "8080"; };
+ serviceConfig = {
+ # The actual command to run
+ ExecStart = "${nodejs}/bin/node ${app}/server.js";
+ # For security reasons we'll run this process as a special 'nodejs' user
+ User = "nodejs";
+ Restart = "always";
+ };
+ };
+
+ # And lastly we ensure the user we run our application as is created
+ users.extraUsers = {
+ nodejs = { };
+ };
+ };
+}
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/abap.abap b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/abap.abap
new file mode 100644
index 0000000..dad93f3
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/abap.abap
@@ -0,0 +1,41 @@
+***************************************
+** Program: EXAMPLE **
+** Author: Joe Byte, 07-Jul-2007 **
+***************************************
+
+REPORT BOOKINGS.
+
+* Read flight bookings from the database
+SELECT * FROM FLIGHTINFO
+ WHERE CLASS = 'Y' "Y = economy
+ OR CLASS = 'C'. "C = business
+(...)
+
+REPORT TEST.
+WRITE 'Hello World'.
+
+USERPROMPT = 'Please double-click on a line in the output list ' &
+ 'to see the complete details of the transaction.'.
+
+
+DATA LAST_EOM TYPE D. "last end-of-month date
+
+* Start from today's date
+ LAST_EOM = SY-DATUM.
+* Set characters 6 and 7 (0-relative) of the YYYYMMDD string to "01",
+* giving the first day of the current month
+ LAST_EOM+6(2) = '01'.
+* Subtract one day
+ LAST_EOM = LAST_EOM - 1.
+
+ WRITE: 'Last day of previous month was', LAST_EOM.
+
+DATA : BEGIN OF I_VBRK OCCURS 0,
+ VBELN LIKE VBRK-VBELN,
+ ZUONR LIKE VBRK-ZUONR,
+ END OF I_VBRK.
+
+SORT i_vbrk BY vbeln ASCENDING.
+SORT i_vbrk BY vbeln DESCENDING.
+
+RETURN.
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/abc.abc b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/abc.abc
new file mode 100644
index 0000000..d8ac326
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/abc.abc
@@ -0,0 +1,171 @@
+%abc-2.1
+H:This file contains some example English tunes
+% note that the comments (like this one) are to highlight usages
+% and would not normally be included in such detail
+O:England % the origin of all tunes is England
+
+X:1 % tune no 1
+T:Dusty Miller, The % title
+T:Binny's Jig % an alternative title
+C:Trad. % traditional
+R:DH % double hornpipe
+M:3/4 % meter
+K:G % key
+B>cd BAG|FA Ac BA|B>cd BAG|DG GB AG:|
+Bdd gfg|aA Ac BA|Bdd gfa|gG GB AG:|
+BG G/2G/2G BG|FA Ac BA|BG G/2G/2G BG|DG GB AG:|
+W:Hey, the dusty miller, and his dusty coat;
+W:He will win a shilling, or he spend a groat.
+W:Dusty was the coat, dusty was the colour;
+W:Dusty was the kiss, that I got frae the miller.
+
+X:2
+T:Old Sir Simon the King
+C:Trad.
+S:Offord MSS % from Offord manuscript
+N:see also Playford % reference note
+M:9/8
+R:SJ % slip jig
+N:originally in C % transcription note
+K:G
+D|GFG GAG G2D|GFG GAG F2D|EFE EFE EFG|A2G F2E D2:|
+D|GAG GAB d2D|GAG GAB c2D|[1 EFE EFE EFG|[A2G] F2E D2:|\ % no line-break in score
+M:12/8 % change of meter
+[2 E2E EFE E2E EFG|\ % no line-break in score
+M:9/8 % change of meter
+A2G F2E D2|]
+
+X:3
+T:William and Nancy
+T:New Mown Hay
+T:Legacy, The
+C:Trad.
+O:England; Gloucs; Bledington % place of origin
+B:Sussex Tune Book % can be found in these books
+B:Mally's Cotswold Morris vol.1 2
+D:Morris On % can be heard on this record
+P:(AB)2(AC)2A % play the parts in this order
+M:6/8
+K:G
+[P:A] D|"G"G2G GBd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
+[P:B] d|"G"e2d B2d|"C"gfe "G"d2d| "G"e2d B2d|"C"gfe "D7"d2c|
+ "G"B2B Bcd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
+% changes of meter, using inline fields
+[T:Slows][M:4/4][L:1/4][P:C]"G"d2|"C"e2 "G"d2|B2 d2|"Em"gf "A7"e2|"D7"d2 "G"d2|\
+ "C"e2 "G"d2|[M:3/8][L:1/8] "G"B2 d |[M:6/8] "C"gfe "D7"d2c|
+ "G"B2B Bcd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
+
+X:4
+T:South Downs Jig
+R:jig
+S:Robert Harbron
+M:6/8
+L:1/8
+K:G
+|: d | dcA G3 | EFG AFE | DEF GAB | cde d2d |
+dcA G3 | EFG AFE | DEF GAB | cAF G2 :|
+B | Bcd e2c | d2B c2A | Bcd e2c | [M:9/8]d2B c2B A3 |
+[M:6/8]DGF E3 | cBA FED | DEF GAB |1 cAF G2 :|2 cAF G3 |]
+
+X:5
+T:Atholl Brose
+% in this example, which reproduces Highland Bagpipe gracing,
+% the large number of grace notes mean that it is more convenient to be specific about
+% score line-breaks (using the $ symbol), rather than using code line breaks to indicate them
+I:linebreak $
+K:D
+{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|
+{gcd}c<{e}A {gAGAG}A>e {ag}a>f {gef}e>d|
+{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|
+{g}c/d/e {g}G>{d}B {gf}gG {dc}d>B:|$
+{g}ce {ag}a>e {gf}g>e|
+{g}ce {ag}a2 {GdG}a>d|
+{g}ce {ag}a>e {gf}g>f|
+{gef}e>d {gf}g>d {gBd}B<{e}G {dc}d>B|
+{g}ce {ag}a>e {gf}g>e|
+{g}ce {ag}a2 {GdG}ad|
+{g}c<{GdG}e {gf}ga {f}g>e {g}f>d|
+{g}e/f/g {Gdc}d>c {gBd}B<{e}G {dc}d2|]
+
+X:6
+T:Untitled Reel
+C:Trad.
+K:D
+eg|a2ab ageg|agbg agef|g2g2 fgag|f2d2 d2:|\
+ed|cecA B2ed|cAcA E2ed|cecA B2ed|c2A2 A2:|
+K:G
+AB|cdec BcdB|ABAF GFE2|cdec BcdB|c2A2 A2:|
+
+X:7
+T:Kitchen Girl
+C:Trad.
+K:D
+[c4a4] [B4g4]|efed c2cd|e2f2 gaba|g2e2 e2fg|
+a4 g4|efed cdef|g2d2 efed|c2A2 A4:|
+K:G
+ABcA BAGB|ABAG EDEG|A2AB c2d2|e3f edcB|ABcA BAGB|
+ABAG EGAB|cBAc BAG2|A4 A4:|
+
+%abc-2.1
+%%pagewidth 21cm
+%%pageheight 29.7cm
+%%topspace 0.5cm
+%%topmargin 1cm
+%%botmargin 0cm
+%%leftmargin 1cm
+%%rightmargin 1cm
+%%titlespace 0cm
+%%titlefont Times-Bold 32
+%%subtitlefont Times-Bold 24
+%%composerfont Times 16
+%%vocalfont Times-Roman 14
+%%staffsep 60pt
+%%sysstaffsep 20pt
+%%musicspace 1cm
+%%vocalspace 5pt
+%%measurenb 0
+%%barsperstaff 5
+%%scale 0.7
+X: 1
+T: Canzonetta a tre voci
+C: Claudio Monteverdi (1567-1643)
+M: C
+L: 1/4
+Q: "Andante mosso" 1/4 = 110
+%%score [1 2 3]
+V: 1 clef=treble name="Soprano"sname="A"
+V: 2 clef=treble name="Alto" sname="T"
+V: 3 clef=bass middle=d name="Tenor" sname="B"
+%%MIDI program 1 75 % recorder
+%%MIDI program 2 75
+%%MIDI program 3 75
+K: Eb
+% 1 - 4
+[V: 1] |:z4 |z4 |f2ec |_ddcc |
+w: Son que-sti~i cre-spi cri-ni~e
+w: Que-sti son gli~oc-chi che mi-
+[V: 2] |:c2BG|AAGc|(F/G/A/B/)c=A|B2AA |
+w: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il vi-so e
+w: Que-sti son~gli oc-chi che mi-ran - - - - do fi-so mi-
+[V: 3] |:z4 |f2ec|_ddcf |(B/c/_d/e/)ff|
+w: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il
+w: Que-sti son~gli oc-chi che mi-ran - - - - do
+% 5 - 9
+[V: 1] cAB2 |cAAA |c3B|G2!fermata!Gz ::e4|
+w: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,
+w: ran-do fi-so, tut-to re-stai con-qui-so.
+[V: 2] AAG2 |AFFF |A3F|=E2!fermata!Ez::c4|
+w: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,
+w: ran-do fi-so tut-to re-stai con-qui-so.
+[V: 3] (ag/f/e2)|A_ddd|A3B|c2!fermata!cz ::A4|
+w: vi - - - so ond' io ti-man-go~uc-ci-so. Deh,
+w: fi - - - so tut-to re-stai con-qui-so.
+% 10 - 15
+[V: 1] f_dec |B2c2|zAGF |\
+w: dim-me-lo ben mi-o, che que-sto\
+=EFG2 |1F2z2:|2F8|] % more notes
+w: sol de-si-o_. % more lyrics
+[V: 2] ABGA |G2AA|GF=EF |(GF3/2=E//D//E)|1F2z2:|2F8|]
+w: dim-me-lo ben mi-o, che que-sto sol de-si - - - - o_.
+[V: 3] _dBc>d|e2AF|=EFc_d|c4 |1F2z2:|2F8|]
+w: dim-me-lo ben mi-o, che que-sto sol de-si-o_.
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/actionscript.as b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/actionscript.as
new file mode 100644
index 0000000..ffe21fb
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/actionscript.as
@@ -0,0 +1,51 @@
+package code
+{
+ /*****************************************
+ * based on textmate actionscript bundle
+ ****************************************/
+
+ import fl.events.SliderEvent;
+
+ public class Foo extends MovieClip
+ {
+ //*************************
+ // Properties:
+
+ public var activeSwatch:MovieClip;
+
+ // Color offsets
+ public var c1:Number = 0; // R
+
+ //*************************
+ // Constructor:
+
+ public function Foo()
+ {
+ // Respond to mouse events
+ swatch1_btn.addEventListener(MouseEvent.CLICK,swatchHandler,false,0,false);
+ previewBox_btn.addEventListener(MouseEvent.MOUSE_DOWN,dragPressHandler);
+
+ // Respond to drag events
+ red_slider.addEventListener(SliderEvent.THUMB_DRAG,sliderHandler);
+
+ // Draw a frame later
+ addEventListener(Event.ENTER_FRAME,draw);
+ }
+
+ protected function clickHandler(event:MouseEvent):void
+ {
+ car.transform.colorTransform = new ColorTransform(0,0,0,1,c1,c2,c3);
+ }
+
+ protected function changeRGBHandler(event:Event):void
+ {
+ c1 = Number(c1_txt.text);
+
+ if(!(c1>=0)){
+ c1 = 0;
+ }
+
+ updateSliders();
+ }
+ }
+}
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/ada.ada b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/ada.ada
new file mode 100644
index 0000000..90e027f
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/ada.ada
@@ -0,0 +1,5 @@
+with Ada.Text_IO; use Ada.Text_IO;
+procedure Hello is
+begin
+ Put_Line("Hello, world!");
+end Hello;
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/apex.apex b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/apex.apex
new file mode 100644
index 0000000..7fbbf6f
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/apex.apex
@@ -0,0 +1,44 @@
+public class testBlockDuplicatesLeadTrigger {
+
+ static testMethod void testDuplicateTrigger(){
+
+ Lead[] l1 =new Lead[]{
+ new Lead( Email='homer@fox.tv', LastName='Simpson', Company='fox' )
+ };
+ insert l1; // add a known lead
+
+ Lead[] l2 =new Lead[]{
+ new Lead( Email='homer@fox.tv', LastName='Simpson', Company='fox' )
+ };
+ // try to add a matching lead
+ try { insert l2; } catch ( System.DmlException e) {
+ system.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists'),
+ e.getMessage());
+ }
+
+ // test duplicates in the same batch
+ Lead[] l3 =new Lead[]{
+ new Lead( Email='marge@fox.tv', LastName='Simpson', Company='fox' ),
+ new Lead( Email='marge@fox.tv', LastName='Simpson', Company='fox' )
+ };
+ try { insert l3; } catch ( System.DmlException e) {
+ system.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Another new lead has the same email'),
+ e.getMessage());
+
+ }
+
+ // test update also
+ Lead[] lup = new Lead[]{
+ new Lead( Email='marge@fox.tv', LastName='Simpson', Company='fox' )
+ };
+ insert lup;
+ Lead marge = [ select id,Email from lead where Email = 'marge@fox.tv' limit 1];
+ system.assert(marge!=null);
+ marge.Email = 'homer@fox.tv';
+
+ try { update marge; } catch ( System.DmlException e) {
+ system.assert(e.getMessage().contains('irst error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists'),
+ e.getMessage());
+ }
+ }
+}
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/aql.aql b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/aql.aql
new file mode 100644
index 0000000..a5baf33
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/aql.aql
@@ -0,0 +1,3 @@
+FOR user IN users
+ FILTER user.username == "olivier"
+ RETURN user
\ No newline at end of file
diff --git a/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/asciidoc.asciidoc b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/asciidoc.asciidoc
new file mode 100644
index 0000000..8cddab5
--- /dev/null
+++ b/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/asciidoc.asciidoc
@@ -0,0 +1,6040 @@
+AsciiDoc User Guide
+===================
+Stuart Rackham
+:Author Initials: SJR
+:toc:
+:icons:
+:numbered:
+:website: http://www.methods.co.nz/asciidoc/
+
+AsciiDoc is a text document format for writing notes, documentation,
+articles, books, ebooks, slideshows, web pages, blogs and UNIX man
+pages. AsciiDoc files can be translated to many formats including
+HTML, PDF, EPUB, man page. AsciiDoc is highly configurable: both the
+AsciiDoc source file syntax and the backend output markups (which can
+be almost any type of SGML/XML markup) can be customized and extended
+by the user.
+
+.This document
+**********************************************************************
+This is an overly large document, it probably needs to be refactored
+into a Tutorial, Quick Reference and Formal Reference.
+
+If you're new to AsciiDoc read this section and the <> section and take a look at the example AsciiDoc (`*.txt`)
+source files in the distribution `doc` directory.
+**********************************************************************
+
+
+Introduction
+------------
+AsciiDoc is a plain text human readable/writable document format that
+can be translated to DocBook or HTML using the asciidoc(1) command.
+You can then either use asciidoc(1) generated HTML directly or run
+asciidoc(1) DocBook output through your favorite DocBook toolchain or
+use the AsciiDoc a2x(1) toolchain wrapper to produce PDF, EPUB, DVI,
+LaTeX, PostScript, man page, HTML and text formats.
+
+The AsciiDoc format is a useful presentation format in its own right:
+AsciiDoc markup is simple, intuitive and as such is easily proofed and
+edited.
+
+AsciiDoc is light weight: it consists of a single Python script and a
+bunch of configuration files. Apart from asciidoc(1) and a Python
+interpreter, no other programs are required to convert AsciiDoc text
+files to DocBook or HTML. See <>
+below.
+
+Text markup conventions tend to be a matter of (often strong) personal
+preference: if the default syntax is not to your liking you can define
+your own by editing the text based asciidoc(1) configuration files.
+You can also create configuration files to translate AsciiDoc
+documents to almost any SGML/XML markup.
+
+asciidoc(1) comes with a set of configuration files to translate
+AsciiDoc articles, books and man pages to HTML or DocBook backend
+formats.
+
+.My AsciiDoc Itch
+**********************************************************************
+DocBook has emerged as the de facto standard Open Source documentation
+format. But DocBook is a complex language, the markup is difficult to
+read and even more difficult to write directly -- I found I was
+spending more time typing markup tags, consulting reference manuals
+and fixing syntax errors, than I was writing the documentation.
+**********************************************************************
+
+
+[[X6]]
+Getting Started
+---------------
+Installing AsciiDoc
+~~~~~~~~~~~~~~~~~~~
+See the `README` and `INSTALL` files for install prerequisites and
+procedures. Packagers take a look at <>.
+
+[[X11]]
+Example AsciiDoc Documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The best way to quickly get a feel for AsciiDoc is to view the
+AsciiDoc web site and/or distributed examples:
+
+- Take a look at the linked examples on the AsciiDoc web site home
+ page {website}. Press the 'Page Source' sidebar menu item to view
+ corresponding AsciiDoc source.
+- Read the `*.txt` source files in the distribution `./doc` directory
+ along with the corresponding HTML and DocBook XML files.
+
+
+AsciiDoc Document Types
+-----------------------
+There are three types of AsciiDoc documents: article, book and
+manpage. All document types share the same AsciiDoc format with some
+minor variations. If you are familiar with DocBook you will have
+noticed that AsciiDoc document types correspond to the same-named
+DocBook document types.
+
+Use the asciidoc(1) `-d` (`--doctype`) option to specify the AsciiDoc
+document type -- the default document type is 'article'.
+
+By convention the `.txt` file extension is used for AsciiDoc document
+source files.
+
+article
+~~~~~~~
+Used for short documents, articles and general documentation. See the
+AsciiDoc distribution `./doc/article.txt` example.
+
+AsciiDoc defines standard DocBook article frontmatter and backmatter
+<> (appendix, abstract, bibliography,
+glossary, index).
+
+book
+~~~~
+Books share the same format as articles, with the following
+differences:
+
+- The part titles in multi-part books are <>
+ (same level as book title).
+- Some sections are book specific e.g. preface and colophon.
+
+Book documents will normally be used to produce DocBook output since
+DocBook processors can automatically generate footnotes, table of
+contents, list of tables, list of figures, list of examples and
+indexes.
+
+AsciiDoc defines standard DocBook book frontmatter and backmatter
+<> (appendix, dedication, preface,
+bibliography, glossary, index, colophon).
+
+.Example book documents
+Book::
+ The `./doc/book.txt` file in the AsciiDoc distribution.
+
+Multi-part book::
+ The `./doc/book-multi.txt` file in the AsciiDoc distribution.
+
+manpage
+~~~~~~~
+Used to generate roff format UNIX manual pages. AsciiDoc manpage
+documents observe special header title and section naming conventions
+-- see the <> section for details.
+
+AsciiDoc defines the 'synopsis' <> to
+generate the DocBook `refsynopsisdiv` section.
+
+See also the asciidoc(1) man page source (`./doc/asciidoc.1.txt`) from
+the AsciiDoc distribution.
+
+
+[[X5]]
+AsciiDoc Backends
+-----------------
+The asciidoc(1) command translates an AsciiDoc formatted file to the
+backend format specified by the `-b` (`--backend`) command-line
+option. asciidoc(1) itself has little intrinsic knowledge of backend
+formats, all translation rules are contained in customizable cascading
+configuration files. Backend specific attributes are listed in the
+<> section.
+
+docbook45::
+ Outputs DocBook XML 4.5 markup.
+
+html4::
+ This backend generates plain HTML 4.01 Transitional markup.
+
+xhtml11::
+ This backend generates XHTML 1.1 markup styled with CSS2. Output
+ files have an `.html` extension.
+
+html5::
+ This backend generates HTML 5 markup, apart from the inclusion of
+ <> it is functionally identical to
+ the 'xhtml11' backend.
+
+slidy::
+ Use this backend to generate self-contained
+ http://www.w3.org/Talks/Tools/Slidy2/[Slidy] HTML slideshows for
+ your web browser from AsciiDoc documents. The Slidy backend is
+ documented in the distribution `doc/slidy.txt` file and
+ {website}slidy.html[online].
+
+wordpress::
+ A minor variant of the 'html4' backend to support
+ http://srackham.wordpress.com/blogpost1/[blogpost].
+
+latex::
+ Experimental LaTeX backend.
+
+Backend Aliases
+~~~~~~~~~~~~~~~
+Backend aliases are alternative names for AsciiDoc backends. AsciiDoc
+comes with two backend aliases: 'html' (aliased to 'xhtml11') and
+'docbook' (aliased to 'docbook45').
+
+You can assign (or reassign) backend aliases by setting an AsciiDoc
+attribute named like `backend-alias-` to an AsciiDoc backend
+name. For example, the following backend alias attribute definitions
+appear in the `[attributes]` section of the global `asciidoc.conf`
+configuration file:
+
+ backend-alias-html=xhtml11
+ backend-alias-docbook=docbook45
+
+[[X100]]
+Backend Plugins
+~~~~~~~~~~~~~~~
+The asciidoc(1) `--backend` option is also used to install and manage
+backend <>.
+
+- A backend plugin is used just like the built-in backends.
+- Backend plugins <> over built-in backends with
+ the same name.
+- You can use the `{asciidoc-confdir}` <> to
+ refer to the built-in backend configuration file location from
+ backend plugin configuration files.
+- You can use the `{backend-confdir}` <> to
+ refer to the backend plugin configuration file location.
+- By default backends plugins are installed in
+ `$HOME/.asciidoc/backends/` where `` is the
+ backend name.
+
+
+DocBook
+-------
+AsciiDoc generates 'article', 'book' and 'refentry'
+http://www.docbook.org/[DocBook] documents (corresponding to the
+AsciiDoc 'article', 'book' and 'manpage' document types).
+
+Most Linux distributions come with conversion tools (collectively
+called a toolchain) for <> to
+presentation formats such as Postscript, HTML, PDF, EPUB, DVI,
+PostScript, LaTeX, roff (the native man page format), HTMLHelp,
+JavaHelp and text. There are also programs that allow you to view
+DocBook files directly, for example http://live.gnome.org/Yelp[Yelp]
+(the GNOME help viewer).
+
+[[X12]]
+Converting DocBook to other file formats
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+DocBook files are validated, parsed and translated various
+presentation file formats using a combination of applications
+collectively called a DocBook 'tool chain'. The function of a tool
+chain is to read the DocBook markup (produced by AsciiDoc) and
+transform it to a presentation format (for example HTML, PDF, HTML
+Help, EPUB, DVI, PostScript, LaTeX).
+
+A wide range of user output format requirements coupled with a choice
+of available tools and stylesheets results in many valid tool chain
+combinations.
+
+[[X43]]
+a2x Toolchain Wrapper
+~~~~~~~~~~~~~~~~~~~~~
+One of the biggest hurdles for new users is installing, configuring
+and using a DocBook XML toolchain. `a2x(1)` can help -- it's a
+toolchain wrapper command that will generate XHTML (chunked and
+unchunked), PDF, EPUB, DVI, PS, LaTeX, man page, HTML Help and text
+file outputs from an AsciiDoc text file. `a2x(1)` does all the grunt
+work associated with generating and sequencing the toolchain commands
+and managing intermediate and output files. `a2x(1)` also optionally
+deploys admonition and navigation icons and a CSS stylesheet. See the
+`a2x(1)` man page for more details. In addition to `asciidoc(1)` you
+also need <>, <> and
+optionally: <> or <> (to generate PDF);
+`w3m(1)` or `lynx(1)` (to generate text).
+
+The following examples generate `doc/source-highlight-filter.pdf` from
+the AsciiDoc `doc/source-highlight-filter.txt` source file. The first
+example uses `dblatex(1)` (the default PDF generator) the second
+example forces FOP to be used:
+
+ $ a2x -f pdf doc/source-highlight-filter.txt
+ $ a2x -f pdf --fop doc/source-highlight-filter.txt
+
+See the `a2x(1)` man page for details.
+
+TIP: Use the `--verbose` command-line option to view executed
+toolchain commands.
+
+HTML generation
+~~~~~~~~~~~~~~~
+AsciiDoc produces nicely styled HTML directly without requiring a
+DocBook toolchain but there are also advantages in going the DocBook
+route:
+
+- HTML from DocBook can optionally include automatically generated
+ indexes, tables of contents, footnotes, lists of figures and tables.
+- DocBook toolchains can also (optionally) generate separate (chunked)
+ linked HTML pages for each document section.
+- Toolchain processing performs link and document validity checks.
+- If the DocBook 'lang' attribute is set then things like table of
+ contents, figure and table captions and admonition captions will be
+ output in the specified language (setting the AsciiDoc 'lang'
+ attribute sets the DocBook 'lang' attribute).
+
+On the other hand, HTML output directly from AsciiDoc is much faster,
+is easily customized and can be used in situations where there is no
+suitable DocBook toolchain (for example, see the {website}[AsciiDoc
+website]).
+
+PDF generation
+~~~~~~~~~~~~~~
+There are two commonly used tools to generate PDFs from DocBook,
+<> and <>.
+
+.dblatex or FOP?
+- 'dblatex' is easier to install, there's zero configuration
+ required and no Java VM to install -- it just works out of the box.
+- 'dblatex' source code highlighting and numbering is superb.
+- 'dblatex' is easier to use as it converts DocBook directly to PDF
+ whereas before using 'FOP' you have to convert DocBook to XML-FO
+ using <>.
+- 'FOP' is more feature complete (for example, callouts are processed
+ inside literal layouts) and arguably produces nicer looking output.
+
+HTML Help generation
+~~~~~~~~~~~~~~~~~~~~
+. Convert DocBook XML documents to HTML Help compiler source files
+ using <> and <>.
+. Convert the HTML Help source (`.hhp` and `.html`) files to HTML Help
+ (`.chm`) files using the <>.
+
+Toolchain components summary
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc::
+ Converts AsciiDoc (`.txt`) files to DocBook XML (`.xml`) files.
+
+[[X13]]http://docbook.sourceforge.net/projects/xsl/[DocBook XSL Stylesheets]::
+ These are a set of XSL stylesheets containing rules for converting
+ DocBook XML documents to HTML, XSL-FO, manpage and HTML Help files.
+ The stylesheets are used in conjunction with an XML parser such as
+ <>.
+
+[[X40]]http://www.xmlsoft.org[xsltproc]::
+ An XML parser for applying XSLT stylesheets (in our case the
+ <>) to XML documents.
+
+[[X31]]http://dblatex.sourceforge.net/[dblatex]::
+ Generates PDF, DVI, PostScript and LaTeX formats directly from
+ DocBook source via the intermediate LaTeX typesetting language --
+ uses <>, <> and
+ `latex(1)`.
+
+[[X14]]http://xml.apache.org/fop/[FOP]::
+ The Apache Formatting Objects Processor converts XSL-FO (`.fo`)
+ files to PDF files. The XSL-FO files are generated from DocBook
+ source files using <> and
+ <>.
+
+[[X67]]Microsoft Help Compiler::
+ The Microsoft HTML Help Compiler (`hhc.exe`) is a command-line tool
+ that converts HTML Help source files to a single HTML Help (`.chm`)
+ file. It runs on MS Windows platforms and can be downloaded from
+ http://www.microsoft.com.
+
+AsciiDoc dblatex configuration files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The AsciiDoc distribution `./dblatex` directory contains
+`asciidoc-dblatex.xsl` (customized XSL parameter settings) and
+`asciidoc-dblatex.sty` (customized LaTeX settings). These are examples
+of optional <> output customization and are used by
+<>.
+
+AsciiDoc DocBook XSL Stylesheets drivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You will have noticed that the distributed HTML and HTML Help
+documentation files (for example `./doc/asciidoc.html`) are not the
+plain outputs produced using the default 'DocBook XSL Stylesheets'
+configuration. This is because they have been processed using
+customized DocBook XSL Stylesheets along with (in the case of HTML
+outputs) the custom `./stylesheets/docbook-xsl.css` CSS stylesheet.
+
+You'll find the customized DocBook XSL drivers along with additional
+documentation in the distribution `./docbook-xsl` directory. The
+examples that follow are executed from the distribution documentation
+(`./doc`) directory. These drivers are also used by <>.
+
+`common.xsl`::
+ Shared driver parameters. This file is not used directly but is
+ included in all the following drivers.
+
+`chunked.xsl`::
+ Generate chunked XHTML (separate HTML pages for each document
+ section) in the `./doc/chunked` directory. For example:
+
+ $ python ../asciidoc.py -b docbook asciidoc.txt
+ $ xsltproc --nonet ../docbook-xsl/chunked.xsl asciidoc.xml
+
+`epub.xsl`::
+ Used by <> to generate EPUB formatted documents.
+
+`fo.xsl`::
+ Generate XSL Formatting Object (`.fo`) files for subsequent PDF
+ file generation using FOP. For example:
+
+ $ python ../asciidoc.py -b docbook article.txt
+ $ xsltproc --nonet ../docbook-xsl/fo.xsl article.xml > article.fo
+ $ fop article.fo article.pdf
+
+`htmlhelp.xsl`::
+ Generate Microsoft HTML Help source files for the MS HTML Help
+ Compiler in the `./doc/htmlhelp` directory. This example is run on
+ MS Windows from a Cygwin shell prompt:
+
+ $ python ../asciidoc.py -b docbook asciidoc.txt
+ $ xsltproc --nonet ../docbook-xsl/htmlhelp.xsl asciidoc.xml
+ $ c:/Program\ Files/HTML\ Help\ Workshop/hhc.exe htmlhelp.hhp
+
+`manpage.xsl`::
+ Generate a `roff(1)` format UNIX man page from a DocBook XML
+ 'refentry' document. This example generates an `asciidoc.1` man
+ page file:
+
+ $ python ../asciidoc.py -d manpage -b docbook asciidoc.1.txt
+ $ xsltproc --nonet ../docbook-xsl/manpage.xsl asciidoc.1.xml
+
+`xhtml.xsl`::
+ Convert a DocBook XML file to a single XHTML file. For example:
+
+ $ python ../asciidoc.py -b docbook asciidoc.txt
+ $ xsltproc --nonet ../docbook-xsl/xhtml.xsl asciidoc.xml > asciidoc.html
+
+If you want to see how the complete documentation set is processed
+take a look at the A-A-P script `./doc/main.aap`.
+
+
+Generating Plain Text Files
+---------------------------
+AsciiDoc does not have a text backend (for most purposes AsciiDoc
+source text is fine), however you can convert AsciiDoc text files to
+formatted text using the AsciiDoc <> toolchain wrapper
+utility.
+
+
+[[X35]]
+HTML5 and XHTML 1.1
+-------------------
+The 'xhtml11' and 'html5' backends embed or link CSS and JavaScript
+files in their outputs, there is also a <> plugin
+framework.
+
+- If the AsciiDoc 'linkcss' attribute is defined then CSS and
+ JavaScript files are linked to the output document, otherwise they
+ are embedded (the default behavior).
+- The default locations for CSS and JavaScript files can be changed by
+ setting the AsciiDoc 'stylesdir' and 'scriptsdir' attributes
+ respectively.
+- The default locations for embedded and linked files differ and are
+ calculated at different times -- embedded files are loaded when
+ asciidoc(1) generates the output document, linked files are loaded
+ by the browser when the user views the output document.
+- Embedded files are automatically inserted in the output files but
+ you need to manually copy linked CSS and Javascript files from
+ AsciiDoc <> to the correct location
+ relative to the output document.
+
+.Stylesheet file locations
+[cols="3*",frame="topbot",options="header"]
+|====================================================================
+|'stylesdir' attribute
+|Linked location ('linkcss' attribute defined)
+|Embedded location ('linkcss' attribute undefined)
+
+|Undefined (default).
+|Same directory as the output document.
+|`stylesheets` subdirectory in the AsciiDoc configuration directory
+(the directory containing the backend conf file).
+
+|Absolute or relative directory name.
+|Absolute or relative to the output document.
+|Absolute or relative to the AsciiDoc configuration directory (the
+directory containing the backend conf file).
+
+|====================================================================
+
+.JavaScript file locations
+[cols="3*",frame="topbot",options="header"]
+|====================================================================
+|'scriptsdir' attribute
+|Linked location ('linkcss' attribute defined)
+|Embedded location ('linkcss' attribute undefined)
+
+|Undefined (default).
+|Same directory as the output document.
+|`javascripts` subdirectory in the AsciiDoc configuration directory
+(the directory containing the backend conf file).
+
+|Absolute or relative directory name.
+|Absolute or relative to the output document.
+|Absolute or relative to the AsciiDoc configuration directory (the
+directory containing the backend conf file).
+
+|====================================================================
+
+[[X99]]
+Themes
+~~~~~~
+The AsciiDoc 'theme' attribute is used to select an alternative CSS
+stylesheet and to optionally include additional JavaScript code.
+
+- Theme files reside in an AsciiDoc <>
+ named `themes//` (where `` is the the theme name set
+ by the 'theme' attribute). asciidoc(1) sets the 'themedir' attribute
+ to the theme directory path name.
+- The 'theme' attribute can also be set using the asciidoc(1)
+ `--theme` option, the `--theme` option can also be used to manage
+ theme <>.
+- AsciiDoc ships with two themes: 'flask' and 'volnitsky'.
+- The `.css` file replaces the default `asciidoc.css` CSS file.
+- The `.js` file is included in addition to the default
+ `asciidoc.js` JavaScript file.
+- If the <> attribute is defined then icons are loaded
+ from the theme `icons` sub-directory if it exists (i.e. the
+ 'iconsdir' attribute is set to theme `icons` sub-directory path).
+- Embedded theme files are automatically inserted in the output files
+ but you need to manually copy linked CSS and Javascript files to the
+ location of the output documents.
+- Linked CSS and JavaScript theme files are linked to the same linked
+ locations as <>.
+
+For example, the command-line option `--theme foo` (or `--attribute
+theme=foo`) will cause asciidoc(1) to search <<"X27","configuration
+file locations 1, 2 and 3">> for a sub-directory called `themes/foo`
+containing the stylesheet `foo.css` and optionally a JavaScript file
+name `foo.js`.
+
+
+Document Structure
+------------------
+An AsciiDoc document consists of a series of <>
+starting with an optional document Header, followed by an optional
+Preamble, followed by zero or more document Sections.
+
+Almost any combination of zero or more elements constitutes a valid
+AsciiDoc document: documents can range from a single sentence to a
+multi-part book.
+
+Block Elements
+~~~~~~~~~~~~~~
+Block elements consist of one or more lines of text and may contain
+other block elements.
+
+The AsciiDoc block structure can be informally summarized as follows
+footnote:[This is a rough structural guide, not a rigorous syntax
+definition]:
+
+ Document ::= (Header?,Preamble?,Section*)
+ Header ::= (Title,(AuthorInfo,RevisionInfo?)?)
+ AuthorInfo ::= (FirstName,(MiddleName?,LastName)?,EmailAddress?)
+ RevisionInfo ::= (RevisionNumber?,RevisionDate,RevisionRemark?)
+ Preamble ::= (SectionBody)
+ Section ::= (Title,SectionBody?,(Section)*)
+ SectionBody ::= ((BlockTitle?,Block)|BlockMacro)+
+ Block ::= (Paragraph|DelimitedBlock|List|Table)
+ List ::= (BulletedList|NumberedList|LabeledList|CalloutList)
+ BulletedList ::= (ListItem)+
+ NumberedList ::= (ListItem)+
+ CalloutList ::= (ListItem)+
+ LabeledList ::= (ListEntry)+
+ ListEntry ::= (ListLabel,ListItem)
+ ListLabel ::= (ListTerm+)
+ ListItem ::= (ItemText,(List|ListParagraph|ListContinuation)*)
+
+Where:
+
+- '?' implies zero or one occurrence, '+' implies one or more
+ occurrences, '*' implies zero or more occurrences.
+- All block elements are separated by line boundaries.
+- `BlockId`, `AttributeEntry` and `AttributeList` block elements (not
+ shown) can occur almost anywhere.
+- There are a number of document type and backend specific
+ restrictions imposed on the block syntax.
+- The following elements cannot contain blank lines: Header, Title,
+ Paragraph, ItemText.
+- A ListParagraph is a Paragraph with its 'listelement' option set.
+- A ListContinuation is a <>.
+
+[[X95]]
+Header
+~~~~~~
+The Header contains document meta-data, typically title plus optional
+authorship and revision information:
+
+- The Header is optional, but if it is used it must start with a
+ document <>.
+- Optional Author and Revision information immediately follows the
+ header title.
+- The document header must be separated from the remainder of the
+ document by one or more blank lines and cannot contain blank lines.
+- The header can include comments.
+- The header can include <>, typically
+ 'doctype', 'lang', 'encoding', 'icons', 'data-uri', 'toc',
+ 'numbered'.
+- Header attributes are overridden by command-line attributes.
+- If the header contains non-UTF-8 characters then the 'encoding' must
+ precede the header (either in the document or on the command-line).
+
+Here's an example AsciiDoc document header:
+
+ Writing Documentation using AsciiDoc
+ ====================================
+ Joe Bloggs
+ v2.0, February 2003:
+ Rewritten for version 2 release.
+
+The author information line contains the author's name optionally
+followed by the author's email address. The author's name is formatted
+like:
+
+ firstname[ [middlename ]lastname][ ]]
+
+i.e. a first name followed by optional middle and last names followed
+by an email address in that order. Multi-word first, middle and last
+names can be entered using the underscore as a word separator. The
+email address comes last and must be enclosed in angle <> brackets.
+Here a some examples of author information lines:
+
+ Joe Bloggs
+ Joe Bloggs
+ Vincent Willem van_Gogh
+
+If the author line does not match the above specification then the
+entire author line is treated as the first name.
+
+The optional revision information line follows the author information
+line. The revision information can be one of two formats:
+
+. An optional document revision number followed by an optional
+ revision date followed by an optional revision remark:
++
+--
+ * If the revision number is specified it must be followed by a
+ comma.
+ * The revision number must contain at least one numeric character.
+ * Any non-numeric characters preceding the first numeric character
+ will be dropped.
+ * If a revision remark is specified it must be preceded by a colon.
+ The revision remark extends from the colon up to the next blank
+ line, attribute entry or comment and is subject to normal text
+ substitutions.
+ * If a revision number or remark has been set but the revision date
+ has not been set then the revision date is set to the value of the
+ 'docdate' attribute.
+
+Examples:
+
+ v2.0, February 2003
+ February 2003
+ v2.0,
+ v2.0, February 2003: Rewritten for version 2 release.
+ February 2003: Rewritten for version 2 release.
+ v2.0,: Rewritten for version 2 release.
+ :Rewritten for version 2 release.
+--
+
+. The revision information line can also be an RCS/CVS/SVN $Id$
+ marker:
++
+--
+ * AsciiDoc extracts the 'revnumber', 'revdate', and 'author'
+ attributes from the $Id$ revision marker and displays them in the
+ document header.
+ * If an $Id$ revision marker is used the header author line can be
+ omitted.
+
+Example:
+
+ $Id: mydoc.txt,v 1.5 2009/05/17 17:58:44 jbloggs Exp $
+--
+
+You can override or set header parameters by passing 'revnumber',
+'revremark', 'revdate', 'email', 'author', 'authorinitials',
+'firstname' and 'lastname' attributes using the asciidoc(1) `-a`
+(`--attribute`) command-line option. For example:
+
+ $ asciidoc -a revdate=2004/07/27 article.txt
+
+Attribute entries can also be added to the header for substitution in
+the header template with <> elements.
+
+The 'title' element in HTML outputs is set to the AsciiDoc document
+title, you can set it to a different value by including a 'title'
+attribute entry in the document header.
+
+[[X87]]
+Additional document header information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+AsciiDoc has two mechanisms for optionally including additional
+meta-data in the header of the output document:
+
+'docinfo' configuration file sections::
+If a <> section named 'docinfo' has been loaded
+then it will be included in the document header. Typically the
+'docinfo' section name will be prefixed with a '+' character so that it
+is appended to (rather than replace) other 'docinfo' sections.
+
+'docinfo' files::
+Two docinfo files are recognized: one named `docinfo` and a second
+named like the AsciiDoc source file with a `-docinfo` suffix. For
+example, if the source document is called `mydoc.txt` then the
+document information files would be `docinfo.xml` and
+`mydoc-docinfo.xml` (for DocBook outputs) and `docinfo.html` and
+`mydoc-docinfo.html` (for HTML outputs). The <> attributes control which docinfo files are included in
+the output files.
+
+The contents docinfo templates and files is dependent on the type of
+output:
+
+HTML::
+ Valid 'head' child elements. Typically 'style' and 'script' elements
+ for CSS and JavaScript inclusion.
+
+DocBook::
+ Valid 'articleinfo' or 'bookinfo' child elements. DocBook defines
+ numerous elements for document meta-data, for example: copyrights,
+ document history and authorship information. See the DocBook
+ `./doc/article-docinfo.xml` example that comes with the AsciiDoc
+ distribution. The rendering of meta-data elements (or not) is
+ DocBook processor dependent.
+
+
+[[X86]]
+Preamble
+~~~~~~~~
+The Preamble is an optional untitled section body between the document
+Header and the first Section title.
+
+Sections
+~~~~~~~~
+In addition to the document title (level 0), AsciiDoc supports four
+section levels: 1 (top) to 4 (bottom). Section levels are delimited
+by section <>. Sections are translated using
+configuration file <>. AsciiDoc
+generates the following <> specifically for
+use in section markup templates:
+
+level::
+The `level` attribute is the section level number, it is normally just
+the <> level number (1..4). However, if the `leveloffset`
+attribute is defined it will be added to the `level` attribute. The
+`leveloffset` attribute is useful for <>.
+
+sectnum::
+The `-n` (`--section-numbers`) command-line option generates the
+`sectnum` (section number) attribute. The `sectnum` attribute is used
+for section numbers in HTML outputs (DocBook section numbering are
+handled automatically by the DocBook toolchain commands).
+
+[[X93]]
+Section markup templates
+^^^^^^^^^^^^^^^^^^^^^^^^
+Section markup templates specify output markup and are defined in
+AsciiDoc configuration files. Section markup template names are
+derived as follows (in order of precedence):
+
+1. From the title's first positional attribute or 'template'
+ attribute. For example, the following three section titles are
+ functionally equivalent:
++
+.....................................................................
+[[terms]]
+[glossary]
+List of Terms
+-------------
+
+["glossary",id="terms"]
+List of Terms
+-------------
+
+[template="glossary",id="terms"]
+List of Terms
+-------------
+.....................................................................
+
+2. When the title text matches a configuration file
+ <> entry.
+3. If neither of the above the default `sect` template is used
+ (where `` is a number from 1 to 4).
+
+In addition to the normal section template names ('sect1', 'sect2',
+'sect3', 'sect4') AsciiDoc has the following templates for
+frontmatter, backmatter and other special sections: 'abstract',
+'preface', 'colophon', 'dedication', 'glossary', 'bibliography',
+'synopsis', 'appendix', 'index'. These special section templates
+generate the corresponding Docbook elements; for HTML outputs they
+default to the 'sect1' section template.
+
+Section IDs
+^^^^^^^^^^^
+If no explicit section ID is specified an ID will be synthesised from
+the section title. The primary purpose of this feature is to ensure
+persistence of table of contents links (permalinks): the missing
+section IDs are generated dynamically by the JavaScript TOC generator
+*after* the page is loaded. If you link to a dynamically generated TOC
+address the page will load but the browser will ignore the (as yet
+ungenerated) section ID.
+
+The IDs are generated by the following algorithm:
+
+- Replace all non-alphanumeric title characters with underscores.
+- Strip leading or trailing underscores.
+- Convert to lowercase.
+- Prepend the `idprefix` attribute (so there's no possibility of name
+ clashes with existing document IDs). Prepend an underscore if the
+ `idprefix` attribute is not defined.
+- A numbered suffix (`_2`, `_3` ...) is added if a same named
+ auto-generated section ID exists.
+- If the `ascii-ids` attribute is defined then non-ASCII characters
+ are replaced with ASCII equivalents. This attribute may be
+ deprecated in future releases and *should be avoided*, it's sole
+ purpose is to accommodate deficient downstream applications that
+ cannot process non-ASCII ID attributes.
+
+Example: the title 'Jim's House' would generate the ID `_jim_s_house`.
+
+Section ID synthesis can be disabled by undefining the `sectids`
+attribute.
+
+[[X16]]
+Special Section Titles
+^^^^^^^^^^^^^^^^^^^^^^
+AsciiDoc has a mechanism for mapping predefined section titles
+auto-magically to specific markup templates. For example a title
+'Appendix A: Code Reference' will automatically use the 'appendix'
+<>. The mappings from title to template
+name are specified in `[specialsections]` sections in the Asciidoc
+language configuration files (`lang-*.conf`). Section entries are
+formatted like:
+
+ =
+
+`` is a Python regular expression and `` is the name
+of a configuration file markup template section. If the ``
+matches an AsciiDoc document section title then the backend output is
+marked up using the `` markup template (instead of the
+default `sect` section template). The `{title}` attribute value
+is set to the value of the matched regular expression group named
+'title', if there is no 'title' group `{title}` defaults to the whole
+of the AsciiDoc section title. If `` is blank then any
+existing entry with the same `` will be deleted.
+
+.Special section titles vs. explicit template names
+*********************************************************************
+AsciiDoc has two mechanisms for specifying non-default section markup
+templates: you can specify the template name explicitly (using the
+'template' attribute) or indirectly (using 'special section titles').
+Specifying a <> attribute explicitly is
+preferred. Auto-magical 'special section titles' have the following
+drawbacks:
+
+- They are non-obvious, you have to know the exact matching
+ title for each special section on a language by language basis.
+- Section titles are predefined and can only be customised with a
+ configuration change.
+- The implementation is complicated by multiple languages: every
+ special section title has to be defined for each language (in each
+ of the `lang-*.conf` files).
+
+Specifying special section template names explicitly does add more
+noise to the source document (the 'template' attribute declaration),
+but the intention is obvious and the syntax is consistent with other
+AsciiDoc elements c.f. bibliographic, Q&A and glossary lists.
+
+Special section titles have been deprecated but are retained for
+backward compatibility.
+
+*********************************************************************
+
+Inline Elements
+~~~~~~~~~~~~~~~
+<> are used to format text and to
+perform various types of text substitution. Inline elements and inline
+element syntax is defined in the asciidoc(1) configuration files.
+
+Here is a list of AsciiDoc inline elements in the (default) order in
+which they are processed:
+
+Special characters::
+ These character sequences escape special characters used by
+ the backend markup (typically `<`, `>`, and `&` characters).
+ See `[specialcharacters]` configuration file sections.
+
+Quotes::
+ Elements that markup words and phrases; usually for character
+ formatting. See `[quotes]` configuration file sections.
+
+Special Words::
+ Word or word phrase patterns singled out for markup without
+ the need for further annotation. See `[specialwords]`
+ configuration file sections.
+
+Replacements::
+ Each replacement defines a word or word phrase pattern to
+ search for along with corresponding replacement text. See
+ `[replacements]` configuration file sections.
+
+Attribute references::
+ Document attribute names enclosed in braces are replaced by
+ the corresponding attribute value.
+
+Inline Macros::
+ Inline macros are replaced by the contents of parametrized
+ configuration file sections.
+
+
+Document Processing
+-------------------
+The AsciiDoc source document is read and processed as follows:
+
+1. The document 'Header' is parsed, header parameter values are
+ substituted into the configuration file `[header]` template section
+ which is then written to the output file.
+2. Each document 'Section' is processed and its constituent elements
+ translated to the output file.
+3. The configuration file `[footer]` template section is substituted
+ and written to the output file.
+
+When a block element is encountered asciidoc(1) determines the type of
+block by checking in the following order (first to last): (section)
+Titles, BlockMacros, Lists, DelimitedBlocks, Tables, AttributeEntrys,
+AttributeLists, BlockTitles, Paragraphs.
+
+The default paragraph definition `[paradef-default]` is last element
+to be checked.
+
+Knowing the parsing order will help you devise unambiguous macro, list
+and block syntax rules.
+
+Inline substitutions within block elements are performed in the
+following default order:
+
+1. Special characters
+2. Quotes
+3. Special words
+4. Replacements
+5. Attributes
+6. Inline Macros
+7. Replacements2
+
+The substitutions and substitution order performed on
+Title, Paragraph and DelimitedBlock elements is determined by
+configuration file parameters.
+
+
+Text Formatting
+---------------
+[[X51]]
+Quoted Text
+~~~~~~~~~~~
+Words and phrases can be formatted by enclosing inline text with
+quote characters:
+
+_Emphasized text_::
+ Word phrases \'enclosed in single quote characters' (acute
+ accents) or \_underline characters_ are emphasized.
+
+*Strong text*::
+ Word phrases \*enclosed in asterisk characters* are rendered
+ in a strong font (usually bold).
+
+[[X81]]+Monospaced text+::
+ Word phrases \+enclosed in plus characters+ are rendered in a
+ monospaced font. Word phrases \`enclosed in backtick
+ characters` (grave accents) are also rendered in a monospaced
+ font but in this case the enclosed text is rendered literally
+ and is not subject to further expansion (see <>).
+
+`Single quoted text'::
+ Phrases enclosed with a \`single grave accent to the left and
+ a single acute accent to the right' are rendered in single
+ quotation marks.
+
+``Double quoted text''::
+ Phrases enclosed with \\``two grave accents to the left and
+ two acute accents to the right'' are rendered in quotation
+ marks.
+
+#Unquoted text#::
+ Placing \#hashes around text# does nothing, it is a mechanism
+ to allow inline attributes to be applied to otherwise
+ unformatted text.
+
+New quote types can be defined by editing asciidoc(1) configuration
+files. See the <> section for details.
+
+.Quoted text behavior
+- Quoting cannot be overlapped.
+- Different quoting types can be nested.
+- To suppress quoted text formatting place a backslash character
+ immediately in front of the leading quote character(s). In the case
+ of ambiguity between escaped and non-escaped text you will need to
+ escape both leading and trailing quotes, in the case of
+ multi-character quotes you may even need to escape individual
+ characters.
+
+[[X96]]
+Quoted text attributes
+^^^^^^^^^^^^^^^^^^^^^^
+Quoted text can be prefixed with an <>. The first
+positional attribute ('role' attribute) is translated by AsciiDoc to
+an HTML 'span' element 'class' attribute or a DocBook 'phrase' element
+'role' attribute.
+
+DocBook XSL Stylesheets translate DocBook 'phrase' elements with
+'role' attributes to corresponding HTML 'span' elements with the same
+'class' attributes; CSS can then be used
+http://www.sagehill.net/docbookxsl/UsingCSS.html[to style the
+generated HTML]. Thus CSS styling can be applied to both DocBook and
+AsciiDoc generated HTML outputs. You can also specify multiple class
+names separated by spaces.
+
+CSS rules for text color, text background color, text size and text
+decorators are included in the distributed AsciiDoc CSS files and are
+used in conjunction with AsciiDoc 'xhtml11', 'html5' and 'docbook'
+outputs. The CSS class names are:
+
+- '' (text foreground color).
+- '-background' (text background color).
+- 'big' and 'small' (text size).
+- 'underline', 'overline' and 'line-through' (strike through) text
+ decorators.
+
+Where '' can be any of the
+http://en.wikipedia.org/wiki/Web_colors#HTML_color_names[sixteen HTML
+color names]. Examples:
+
+ [red]#Obvious# and [big red yellow-background]*very obvious*.
+
+ [underline]#Underline text#, [overline]#overline text# and
+ [blue line-through]*bold blue and line-through*.
+
+is rendered as:
+
+[red]#Obvious# and [big red yellow-background]*very obvious*.
+
+[underline]#Underline text#, [overline]#overline text# and
+[bold blue line-through]*bold blue and line-through*.
+
+NOTE: Color and text decorator attributes are rendered for XHTML and
+HTML 5 outputs using CSS stylesheets. The mechanism to implement
+color and text decorator attributes is provided for DocBook toolchains
+via the DocBook 'phrase' element 'role' attribute, but the actual
+rendering is toolchain specific and is not part of the AsciiDoc
+distribution.
+
+[[X52]]
+Constrained and Unconstrained Quotes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+There are actually two types of quotes:
+
+Constrained quotes
+++++++++++++++++++
+Quoted must be bounded by white space or commonly adjoining
+punctuation characters. These are the most commonly used type of
+quote.
+
+Unconstrained quotes
+++++++++++++++++++++
+Unconstrained quotes have no boundary constraints and can be placed
+anywhere within inline text. For consistency and to make them easier
+to remember unconstrained quotes are double-ups of the `_`, `*`, `+`
+and `#` constrained quotes:
+
+ __unconstrained emphasized text__
+ **unconstrained strong text**
+ ++unconstrained monospaced text++
+ ##unconstrained unquoted text##
+
+The following example emboldens the letter F:
+
+ **F**ile Open...
+
+Superscripts and Subscripts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Put \^carets on either^ side of the text to be superscripted, put
+\~tildes on either side~ of text to be subscripted. For example, the
+following line:
+
+ e^πi^+1 = 0. H~2~O and x^10^. Some ^super text^
+ and ~some sub text~
+
+Is rendered like:
+
+e^πi^+1 = 0. H~2~O and x^10^. Some ^super text^
+and ~some sub text~
+
+Superscripts and subscripts are implemented as <> and they can be escaped with a leading backslash and prefixed
+with with an attribute list.
+
+Line Breaks
+~~~~~~~~~~~
+A plus character preceded by at least one space character at the end
+of a non-blank line forces a line break. It generates a line break
+(`br`) tag for HTML outputs and a custom XML `asciidoc-br` processing
+instruction for DocBook outputs. The `asciidoc-br` processing
+instruction is handled by <>.
+
+Page Breaks
+~~~~~~~~~~~
+A line of three or more less-than (`<<<`) characters will generate a
+hard page break in DocBook and printed HTML outputs. It uses the CSS
+`page-break-after` property for HTML outputs and a custom XML
+`asciidoc-pagebreak` processing instruction for DocBook outputs. The
+`asciidoc-pagebreak` processing instruction is handled by
+<>. Hard page breaks are sometimes handy but as a general
+rule you should let your page processor generate page breaks for you.
+
+Rulers
+~~~~~~
+A line of three or more apostrophe characters will generate a ruler
+line. It generates a ruler (`hr`) tag for HTML outputs and a custom
+XML `asciidoc-hr` processing instruction for DocBook outputs. The
+`asciidoc-hr` processing instruction is handled by <>.
+
+Tabs
+~~~~
+By default tab characters input files will translated to 8 spaces. Tab
+expansion is set with the 'tabsize' entry in the configuration file
+`[miscellaneous]` section and can be overridden in included files by
+setting a 'tabsize' attribute in the `include` macro's attribute list.
+For example:
+
+ include::addendum.txt[tabsize=2]
+
+The tab size can also be set using the attribute command-line option,
+for example `--attribute tabsize=4`
+
+Replacements
+~~~~~~~~~~~~
+The following replacements are defined in the default AsciiDoc
+configuration:
+
+ (C) copyright, (TM) trademark, (R) registered trademark,
+ -- em dash, ... ellipsis, -> right arrow, <- left arrow, => right
+ double arrow, <= left double arrow.
+
+Which are rendered as:
+
+(C) copyright, (TM) trademark, (R) registered trademark,
+-- em dash, ... ellipsis, -> right arrow, <- left arrow, => right
+double arrow, <= left double arrow.
+
+You can also include arbitrary entity references in the AsciiDoc
+source. Examples:
+
+ ➊ ¶
+
+renders:
+
+➊ ¶
+
+To render a replacement literally escape it with a leading back-slash.
+
+The <> section explains how to configure your
+own replacements.
+
+Special Words
+~~~~~~~~~~~~~
+Words defined in `[specialwords]` configuration file sections are
+automatically marked up without having to be explicitly notated.
+
+The <> section explains how to add and replace
+special words.
+
+
+[[X17]]
+Titles
+------
+Document and section titles can be in either of two formats:
+
+Two line titles
+~~~~~~~~~~~~~~~
+A two line title consists of a title line, starting hard against the
+left margin, and an underline. Section underlines consist a repeated
+character pairs spanning the width of the preceding title (give or
+take up to two characters):
+
+The default title underlines for each of the document levels are:
+
+
+ Level 0 (top level): ======================
+ Level 1: ----------------------
+ Level 2: ~~~~~~~~~~~~~~~~~~~~~~
+ Level 3: ^^^^^^^^^^^^^^^^^^^^^^
+ Level 4 (bottom level): ++++++++++++++++++++++
+
+Examples:
+
+ Level One Section Title
+ -----------------------
+
+ Level 2 Subsection Title
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[X46]]
+One line titles
+~~~~~~~~~~~~~~~
+One line titles consist of a single line delimited on either side by
+one or more equals characters (the number of equals characters
+corresponds to the section level minus one). Here are some examples:
+
+ = Document Title (level 0) =
+ == Section title (level 1) ==
+ === Section title (level 2) ===
+ ==== Section title (level 3) ====
+ ===== Section title (level 4) =====
+
+[NOTE]
+=====================================================================
+- One or more spaces must fall between the title and the delimiters.
+- The trailing title delimiter is optional.
+- The one-line title syntax can be changed by editing the
+ configuration file `[titles]` section `sect0`...`sect4` entries.
+=====================================================================
+
+Floating titles
+~~~~~~~~~~~~~~~
+Setting the title's first positional attribute or 'style' attribute to
+'float' generates a free-floating title. A free-floating title is
+rendered just like a normal section title but is not formally
+associated with a text body and is not part of the regular section
+hierarchy so the normal ordering rules do not apply. Floating titles
+can also be used in contexts where section titles are illegal: for
+example sidebar and admonition blocks. Example:
+
+ [float]
+ The second day
+ ~~~~~~~~~~~~~~
+
+Floating titles do not appear in a document's table of contents.
+
+
+[[X42]]
+Block Titles
+------------
+A 'BlockTitle' element is a single line beginning with a period
+followed by the title text. A BlockTitle is applied to the immediately
+following Paragraph, DelimitedBlock, List, Table or BlockMacro. For
+example:
+
+........................
+.Notes
+- Note 1.
+- Note 2.
+........................
+
+is rendered as:
+
+.Notes
+- Note 1.
+- Note 2.
+
+
+[[X41]]
+BlockId Element
+---------------
+A 'BlockId' is a single line block element containing a unique
+identifier enclosed in double square brackets. It is used to assign an
+identifier to the ensuing block element. For example:
+
+ [[chapter-titles]]
+ Chapter titles can be ...
+
+The preceding example identifies the ensuing paragraph so it can be
+referenced from other locations, for example with
+`<>`.
+
+'BlockId' elements can be applied to Title, Paragraph, List,
+DelimitedBlock, Table and BlockMacro elements. The BlockId element
+sets the `{id}` attribute for substitution in the subsequent block's
+markup template. If a second positional argument is supplied it sets
+the `{reftext}` attribute which is used to set the DocBook `xreflabel`
+attribute.
+
+The 'BlockId' element has the same syntax and serves the same function
+to the <>.
+
+[[X79]]
+AttributeList Element
+---------------------
+An 'AttributeList' block element is an <> on a
+line by itself:
+
+- 'AttributeList' attributes are only applied to the immediately
+ following block element -- the attributes are made available to the
+ block's markup template.
+- Multiple contiguous 'AttributeList' elements are additively combined
+ in the order they appear..
+- The first positional attribute in the list is often used to specify
+ the ensuing element's <>.
+
+Attribute value substitution
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+By default, only substitutions that take place inside attribute list
+values are attribute references, this is because not all attributes
+are destined to be marked up and rendered as text (for example the
+table 'cols' attribute). To perform normal inline text substitutions
+(special characters, quotes, macros, replacements) on an attribute
+value you need to enclose it in single quotes. In the following quote
+block the second attribute value in the AttributeList is quoted to
+ensure the 'http' macro is expanded to a hyperlink.
+
+---------------------------------------------------------------------
+[quote,'http://en.wikipedia.org/wiki/Samuel_Johnson[Samuel Johnson]']
+_____________________________________________________________________
+Sir, a woman's preaching is like a dog's walking on his hind legs. It
+is not done well; but you are surprised to find it done at all.
+_____________________________________________________________________
+---------------------------------------------------------------------
+
+Common attributes
+~~~~~~~~~~~~~~~~~
+Most block elements support the following attributes:
+
+[cols="1e,1,5a",frame="topbot",options="header"]
+|====================================================================
+|Name |Backends |Description
+
+|id |html4, html5, xhtml11, docbook |
+Unique identifier typically serve as link targets.
+Can also be set by the 'BlockId' element.
+
+|role |html4, html5, xhtml11, docbook |
+Role contains a string used to classify or subclassify an element and
+can be applied to AsciiDoc block elements. The AsciiDoc 'role'
+attribute is translated to the 'role' attribute in DocBook outputs and
+is included in the 'class' attribute in HTML outputs, in this respect
+it behaves like the <>.
+
+DocBook XSL Stylesheets translate DocBook 'role' attributes to HTML
+'class' attributes; CSS can then be used
+http://www.sagehill.net/docbookxsl/UsingCSS.html[to style the
+generated HTML].
+
+|reftext |docbook |
+'reftext' is used to set the DocBook 'xreflabel' attribute.
+The 'reftext' attribute can an also be set by the 'BlockId' element.
+
+|====================================================================
+
+
+Paragraphs
+----------
+Paragraphs are blocks of text terminated by a blank line, the end of
+file, or the start of a delimited block or a list. There are three
+paragraph syntaxes: normal, indented (literal) and admonition which
+are rendered, by default, with the corresponding paragraph style.
+
+Each syntax has a default style, but you can explicitly apply any
+paragraph style to any paragraph syntax. You can also apply
+<> styles to single paragraphs.
+
+The built-in paragraph styles are: 'normal', 'literal', 'verse',
+'quote', 'listing', 'TIP', 'NOTE', 'IMPORTANT', 'WARNING', 'CAUTION',
+'abstract', 'partintro', 'comment', 'example', 'sidebar', 'source',
+'music', 'latex', 'graphviz'.
+
+normal paragraph syntax
+~~~~~~~~~~~~~~~~~~~~~~~
+Normal paragraph syntax consists of one or more non-blank lines of
+text. The first line must start hard against the left margin (no
+intervening white space). The default processing expectation is that
+of a normal paragraph of text.
+
+[[X85]]
+literal paragraph syntax
+~~~~~~~~~~~~~~~~~~~~~~~~
+Literal paragraphs are rendered verbatim in a monospaced font without
+any distinguishing background or border. By default there is no text
+formatting or substitutions within Literal paragraphs apart from
+Special Characters and Callouts.
+
+The 'literal' style is applied implicitly to indented paragraphs i.e.
+where the first line of the paragraph is indented by one or more space
+or tab characters. For example:
+
+---------------------------------------------------------------------
+ Consul *necessitatibus* per id,
+ consetetur, eu pro everti postulant
+ homero verear ea mea, qui.
+---------------------------------------------------------------------
+
+Renders:
+
+ Consul *necessitatibus* per id,
+ consetetur, eu pro everti postulant
+ homero verear ea mea, qui.
+
+NOTE: Because <> can be indented it's possible for your
+indented paragraph to be misinterpreted as a list -- in situations
+like this apply the 'literal' style to a normal paragraph.
+
+Instead of using a paragraph indent you could apply the 'literal'
+style explicitly, for example:
+
+---------------------------------------------------------------------
+[literal]
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+---------------------------------------------------------------------
+
+Renders:
+
+[literal]
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+
+[[X94]]
+quote and verse paragraph styles
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The optional 'attribution' and 'citetitle' attributes (positional
+attributes 2 and 3) specify the author and source respectively.
+
+The 'verse' style retains the line breaks, for example:
+
+---------------------------------------------------------------------
+[verse, William Blake, from Auguries of Innocence]
+To see a world in a grain of sand,
+And a heaven in a wild flower,
+Hold infinity in the palm of your hand,
+And eternity in an hour.
+---------------------------------------------------------------------
+
+Which is rendered as:
+
+[verse, William Blake, from Auguries of Innocence]
+To see a world in a grain of sand,
+And a heaven in a wild flower,
+Hold infinity in the palm of your hand,
+And eternity in an hour.
+
+The 'quote' style flows the text at left and right margins, for
+example:
+
+---------------------------------------------------------------------
+[quote, Bertrand Russell, The World of Mathematics (1956)]
+A good notation has subtlety and suggestiveness which at times makes
+it almost seem like a live teacher.
+---------------------------------------------------------------------
+
+Which is rendered as:
+
+[quote, Bertrand Russell, The World of Mathematics (1956)]
+A good notation has subtlety and suggestiveness which at times makes
+it almost seem like a live teacher.
+
+[[X28]]
+Admonition Paragraphs
+~~~~~~~~~~~~~~~~~~~~~
+'TIP', 'NOTE', 'IMPORTANT', 'WARNING' and 'CAUTION' admonishment
+paragraph styles are generated by placing `NOTE:`, `TIP:`,
+`IMPORTANT:`, `WARNING:` or `CAUTION:` as the first word of the
+paragraph. For example:
+
+ NOTE: This is an example note.
+
+Alternatively, you can specify the paragraph admonition style
+explicitly using an <>. For example:
+
+ [NOTE]
+ This is an example note.
+
+Renders:
+
+NOTE: This is an example note.
+
+TIP: If your admonition requires more than a single paragraph use an
+<> instead.
+
+[[X47]]
+Admonition Icons and Captions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+NOTE: Admonition customization with `icons`, `iconsdir`, `icon` and
+`caption` attributes does not apply when generating DocBook output. If
+you are going the DocBook route then the <> `--no-icons`
+and `--icons-dir` options can be used to set the appropriate XSL
+Stylesheets parameters.
+
+By default the asciidoc(1) HTML backends generate text captions
+instead of admonition icon image links. To generate links to icon
+images define the <> attribute, for example using the `-a
+icons` command-line option.
+
+The <> attribute sets the location of linked icon
+images.
+
+You can override the default icon image using the `icon` attribute to
+specify the path of the linked image. For example:
+
+ [icon="./images/icons/wink.png"]
+ NOTE: What lovely war.
+
+Use the `caption` attribute to customize the admonition captions (not
+applicable to `docbook` backend). The following example suppresses the
+icon image and customizes the caption of a 'NOTE' admonition
+(undefining the `icons` attribute with `icons=None` is only necessary
+if <> have been enabled):
+
+ [icons=None, caption="My Special Note"]
+ NOTE: This is my special note.
+
+This subsection also applies to <>.
+
+
+[[X104]]
+Delimited Blocks
+----------------
+Delimited blocks are blocks of text enveloped by leading and trailing
+delimiter lines (normally a series of four or more repeated
+characters). The behavior of Delimited Blocks is specified by entries
+in configuration file `[blockdef-*]` sections.
+
+Predefined Delimited Blocks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc ships with a number of predefined DelimitedBlocks (see the
+`asciidoc.conf` configuration file in the asciidoc(1) program
+directory):
+
+Predefined delimited block underlines:
+
+ CommentBlock: //////////////////////////
+ PassthroughBlock: ++++++++++++++++++++++++++
+ ListingBlock: --------------------------
+ LiteralBlock: ..........................
+ SidebarBlock: **************************
+ QuoteBlock: __________________________
+ ExampleBlock: ==========================
+ OpenBlock: --
+
+.Default DelimitedBlock substitutions
+[cols="2e,7*^",frame="topbot",options="header,autowidth"]
+|=====================================================
+| |Attributes |Callouts |Macros | Quotes |Replacements
+|Special chars |Special words
+
+|PassthroughBlock |Yes |No |Yes |No |No |No |No
+|ListingBlock |No |Yes |No |No |No |Yes |No
+|LiteralBlock |No |Yes |No |No |No |Yes |No
+|SidebarBlock |Yes |No |Yes |Yes |Yes |Yes |Yes
+|QuoteBlock |Yes |No |Yes |Yes |Yes |Yes |Yes
+|ExampleBlock |Yes |No |Yes |Yes |Yes |Yes |Yes
+|OpenBlock |Yes |No |Yes |Yes |Yes |Yes |Yes
+|=====================================================
+
+Listing Blocks
+~~~~~~~~~~~~~~
+'ListingBlocks' are rendered verbatim in a monospaced font, they
+retain line and whitespace formatting and are often distinguished by a
+background or border. There is no text formatting or substitutions
+within Listing blocks apart from Special Characters and Callouts.
+Listing blocks are often used for computer output and file listings.
+
+Here's an example:
+
+[listing]
+......................................
+--------------------------------------
+#include
+
+int main() {
+ printf("Hello World!\n");
+ exit(0);
+}
+--------------------------------------
+......................................
+
+Which will be rendered like:
+
+--------------------------------------
+#include
+
+int main() {
+ printf("Hello World!\n");
+ exit(0);
+}
+--------------------------------------
+
+By convention <> use the listing block syntax and
+are implemented as distinct listing block styles.
+
+[[X65]]
+Literal Blocks
+~~~~~~~~~~~~~~
+'LiteralBlocks' are rendered just like <>.
+Example:
+
+---------------------------------------------------------------------
+...................................
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+...................................
+---------------------------------------------------------------------
+
+Renders:
+...................................
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+...................................
+
+If the 'listing' style is applied to a LiteralBlock it will be
+rendered as a ListingBlock (this is handy if you have a listing
+containing a ListingBlock).
+
+Sidebar Blocks
+~~~~~~~~~~~~~~
+A sidebar is a short piece of text presented outside the narrative
+flow of the main text. The sidebar is normally presented inside a
+bordered box to set it apart from the main text.
+
+The sidebar body is treated like a normal section body.
+
+Here's an example:
+
+---------------------------------------------------------------------
+.An Example Sidebar
+************************************************
+Any AsciiDoc SectionBody element (apart from
+SidebarBlocks) can be placed inside a sidebar.
+************************************************
+---------------------------------------------------------------------
+
+Which will be rendered like:
+
+.An Example Sidebar
+************************************************
+Any AsciiDoc SectionBody element (apart from
+SidebarBlocks) can be placed inside a sidebar.
+************************************************
+
+[[X26]]
+Comment Blocks
+~~~~~~~~~~~~~~
+The contents of 'CommentBlocks' are not processed; they are useful for
+annotations and for excluding new or outdated content that you don't
+want displayed. CommentBlocks are never written to output files.
+Example:
+
+---------------------------------------------------------------------
+//////////////////////////////////////////
+CommentBlock contents are not processed by
+asciidoc(1).
+//////////////////////////////////////////
+---------------------------------------------------------------------
+
+See also <>.
+
+NOTE: System macros are executed inside comment blocks.
+
+[[X76]]
+Passthrough Blocks
+~~~~~~~~~~~~~~~~~~
+By default the block contents is subject only to 'attributes' and
+'macros' substitutions (use an explicit 'subs' attribute to apply
+different substitutions). PassthroughBlock content will often be
+backend specific. Here's an example:
+
+---------------------------------------------------------------------
+[subs="quotes"]
+++++++++++++++++++++++++++++++++++++++
+
+
*Cell 1*
+
*Cell 2*
+
+++++++++++++++++++++++++++++++++++++++
+---------------------------------------------------------------------
+
+The following styles can be applied to passthrough blocks:
+
+pass::
+ No substitutions are performed. This is equivalent to `subs="none"`.
+
+asciimath, latexmath::
+ By default no substitutions are performed, the contents are rendered
+ as <>.
+
+Quote Blocks
+~~~~~~~~~~~~
+'QuoteBlocks' are used for quoted passages of text. There are two
+styles: 'quote' and 'verse'. The style behavior is identical to
+<> except that blocks can contain
+multiple paragraphs and, in the case of the 'quote' style, other
+section elements. The first positional attribute sets the style, if
+no attributes are specified the 'quote' style is used. The optional
+'attribution' and 'citetitle' attributes (positional attributes 2 and
+3) specify the quote's author and source. For example:
+
+---------------------------------------------------------------------
+[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]
+____________________________________________________________________
+As he spoke there was the sharp sound of horses' hoofs and
+grating wheels against the curb, followed by a sharp pull at the
+bell. Holmes whistled.
+
+"A pair, by the sound," said he. "Yes," he continued, glancing
+out of the window. "A nice little brougham and a pair of
+beauties. A hundred and fifty guineas apiece. There's money in
+this case, Watson, if there is nothing else."
+____________________________________________________________________
+---------------------------------------------------------------------
+
+Which is rendered as:
+
+[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]
+____________________________________________________________________
+As he spoke there was the sharp sound of horses' hoofs and
+grating wheels against the curb, followed by a sharp pull at the
+bell. Holmes whistled.
+
+"A pair, by the sound," said he. "Yes," he continued, glancing
+out of the window. "A nice little brougham and a pair of
+beauties. A hundred and fifty guineas apiece. There's money in
+this case, Watson, if there is nothing else."
+____________________________________________________________________
+
+[[X48]]
+Example Blocks
+~~~~~~~~~~~~~~
+'ExampleBlocks' encapsulate the DocBook Example element and are used
+for, well, examples. Example blocks can be titled by preceding them
+with a 'BlockTitle'. DocBook toolchains will normally automatically
+number examples and generate a 'List of Examples' backmatter section.
+
+Example blocks are delimited by lines of equals characters and can
+contain any block elements apart from Titles, BlockTitles and
+Sidebars) inside an example block. For example:
+
+---------------------------------------------------------------------
+.An example
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+=====================================================================
+---------------------------------------------------------------------
+
+Renders:
+
+.An example
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+=====================================================================
+
+A title prefix that can be inserted with the `caption` attribute
+(HTML backends). For example:
+
+---------------------------------------------------------------------
+[caption="Example 1: "]
+.An example with a custom caption
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+=====================================================================
+---------------------------------------------------------------------
+
+[[X22]]
+Admonition Blocks
+~~~~~~~~~~~~~~~~~
+The 'ExampleBlock' definition includes a set of admonition
+<> ('NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION') for
+generating admonition blocks (admonitions containing more than a
+<>). Just precede the 'ExampleBlock' with an
+attribute list specifying the admonition style name. For example:
+
+---------------------------------------------------------------------
+[NOTE]
+.A NOTE admonition block
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+
+. Fusce euismod commodo velit.
+. Vivamus fringilla mi eu lacus.
+ .. Fusce euismod commodo velit.
+ .. Vivamus fringilla mi eu lacus.
+. Donec eget arcu bibendum
+ nunc consequat lobortis.
+=====================================================================
+---------------------------------------------------------------------
+
+Renders:
+
+[NOTE]
+.A NOTE admonition block
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+
+. Fusce euismod commodo velit.
+. Vivamus fringilla mi eu lacus.
+ .. Fusce euismod commodo velit.
+ .. Vivamus fringilla mi eu lacus.
+. Donec eget arcu bibendum
+ nunc consequat lobortis.
+=====================================================================
+
+See also <>.
+
+[[X29]]
+Open Blocks
+~~~~~~~~~~~
+Open blocks are special:
+
+- The open block delimiter is line containing two hyphen characters
+ (instead of four or more repeated characters).
+
+- They can be used to group block elements for <>.
+
+- Open blocks can be styled to behave like any other type of delimited
+ block. The following built-in styles can be applied to open
+ blocks: 'literal', 'verse', 'quote', 'listing', 'TIP', 'NOTE',
+ 'IMPORTANT', 'WARNING', 'CAUTION', 'abstract', 'partintro',
+ 'comment', 'example', 'sidebar', 'source', 'music', 'latex',
+ 'graphviz'. For example, the following open block and listing block
+ are functionally identical:
+
+ [listing]
+ --
+ Lorum ipsum ...
+ --
+
+ ---------------
+ Lorum ipsum ...
+ ---------------
+
+- An unstyled open block groups section elements but otherwise does
+ nothing.
+
+Open blocks are used to generate document abstracts and book part
+introductions:
+
+- Apply the 'abstract' style to generate an abstract, for example:
+
+ [abstract]
+ --
+ In this paper we will ...
+ --
+
+. Apply the 'partintro' style to generate a book part introduction for
+ a multi-part book, for example:
+
+ [partintro]
+ .Optional part introduction title
+ --
+ Optional part introduction goes here.
+ --
+
+
+[[X64]]
+Lists
+-----
+.List types
+- Bulleted lists. Also known as itemized or unordered lists.
+- Numbered lists. Also called ordered lists.
+- Labeled lists. Sometimes called variable or definition lists.
+- Callout lists (a list of callout annotations).
+
+.List behavior
+- List item indentation is optional and does not determine nesting,
+ indentation does however make the source more readable.
+- Another list or a literal paragraph immediately following a list
+ item will be implicitly included in the list item; use <> to explicitly append other block elements to a
+ list item.
+- A comment block or a comment line block macro element will terminate
+ a list -- use inline comment lines to put comments inside lists.
+- The `listindex` <> is the current list item
+ index (1..). If this attribute is used outside a list then it's value
+ is the number of items in the most recently closed list. Useful for
+ displaying the number of items in a list.
+
+Bulleted Lists
+~~~~~~~~~~~~~~
+Bulleted list items start with a single dash or one to five asterisks
+followed by some white space then some text. Bulleted list syntaxes
+are:
+
+...................
+- List item.
+* List item.
+** List item.
+*** List item.
+**** List item.
+***** List item.
+...................
+
+Numbered Lists
+~~~~~~~~~~~~~~
+List item numbers are explicit or implicit.
+
+.Explicit numbering
+List items begin with a number followed by some white space then the
+item text. The numbers can be decimal (arabic), roman (upper or lower
+case) or alpha (upper or lower case). Decimal and alpha numbers are
+terminated with a period, roman numbers are terminated with a closing
+parenthesis. The different terminators are necessary to ensure 'i',
+'v' and 'x' roman numbers are are distinguishable from 'x', 'v' and
+'x' alpha numbers. Examples:
+
+.....................................................................
+1. Arabic (decimal) numbered list item.
+a. Lower case alpha (letter) numbered list item.
+F. Upper case alpha (letter) numbered list item.
+iii) Lower case roman numbered list item.
+IX) Upper case roman numbered list item.
+.....................................................................
+
+.Implicit numbering
+List items begin one to five period characters, followed by some white
+space then the item text. Examples:
+
+.....................................................................
+. Arabic (decimal) numbered list item.
+.. Lower case alpha (letter) numbered list item.
+... Lower case roman numbered list item.
+.... Upper case alpha (letter) numbered list item.
+..... Upper case roman numbered list item.
+.....................................................................
+
+You can use the 'style' attribute (also the first positional
+attribute) to specify an alternative numbering style. The numbered
+list style can be one of the following values: 'arabic', 'loweralpha',
+'upperalpha', 'lowerroman', 'upperroman'.
+
+Here are some examples of bulleted and numbered lists:
+
+---------------------------------------------------------------------
+- Praesent eget purus quis magna eleifend eleifend.
+ 1. Fusce euismod commodo velit.
+ a. Fusce euismod commodo velit.
+ b. Vivamus fringilla mi eu lacus.
+ c. Donec eget arcu bibendum nunc consequat lobortis.
+ 2. Vivamus fringilla mi eu lacus.
+ i) Fusce euismod commodo velit.
+ ii) Vivamus fringilla mi eu lacus.
+ 3. Donec eget arcu bibendum nunc consequat lobortis.
+ 4. Nam fermentum mattis ante.
+- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+ * Fusce euismod commodo velit.
+ ** Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+ adolescens. Sit munere ponderum dignissim et. Minim luptatum et
+ vel.
+ ** Vivamus fringilla mi eu lacus.
+ * Donec eget arcu bibendum nunc consequat lobortis.
+- Nulla porttitor vulputate libero.
+ . Fusce euismod commodo velit.
+ . Vivamus fringilla mi eu lacus.
+[upperroman]
+ .. Fusce euismod commodo velit.
+ .. Vivamus fringilla mi eu lacus.
+ . Donec eget arcu bibendum nunc consequat lobortis.
+---------------------------------------------------------------------
+
+Which render as:
+
+- Praesent eget purus quis magna eleifend eleifend.
+ 1. Fusce euismod commodo velit.
+ a. Fusce euismod commodo velit.
+ b. Vivamus fringilla mi eu lacus.
+ c. Donec eget arcu bibendum nunc consequat lobortis.
+ 2. Vivamus fringilla mi eu lacus.
+ i) Fusce euismod commodo velit.
+ ii) Vivamus fringilla mi eu lacus.
+ 3. Donec eget arcu bibendum nunc consequat lobortis.
+ 4. Nam fermentum mattis ante.
+- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+ * Fusce euismod commodo velit.
+ ** Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+ adolescens. Sit munere ponderum dignissim et. Minim luptatum et
+ vel.
+ ** Vivamus fringilla mi eu lacus.
+ * Donec eget arcu bibendum nunc consequat lobortis.
+- Nulla porttitor vulputate libero.
+ . Fusce euismod commodo velit.
+ . Vivamus fringilla mi eu lacus.
+[upperroman]
+ .. Fusce euismod commodo velit.
+ .. Vivamus fringilla mi eu lacus.
+ . Donec eget arcu bibendum nunc consequat lobortis.
+
+A predefined 'compact' option is available to bulleted and numbered
+lists -- this translates to the DocBook 'spacing="compact"' lists
+attribute which may or may not be processed by the DocBook toolchain.
+Example:
+
+ [options="compact"]
+ - Compact list item.
+ - Another compact list item.
+
+TIP: To apply the 'compact' option globally define a document-wide
+'compact-option' attribute, e.g. using the `-a compact-option`
+command-line option.
+
+You can set the list start number using the 'start' attribute (works
+for HTML outputs and DocBook outputs processed by DocBook XSL
+Stylesheets). Example:
+
+ [start=7]
+ . List item 7.
+ . List item 8.
+
+Labeled Lists
+~~~~~~~~~~~~~
+Labeled list items consist of one or more text labels followed by the
+text of the list item.
+
+An item label begins a line with an alphanumeric character hard
+against the left margin and ends with two, three or four colons or two
+semi-colons. A list item can have multiple labels, one per line.
+
+The list item text consists of one or more lines of text starting
+after the last label (either on the same line or a new line) and can
+be followed by nested List or ListParagraph elements. Item text can be
+optionally indented.
+
+Here are some examples:
+
+---------------------------------------------------------------------
+In::
+Lorem::
+ Fusce euismod commodo velit.
+
+ Fusce euismod commodo velit.
+
+Ipsum:: Vivamus fringilla mi eu lacus.
+ * Vivamus fringilla mi eu lacus.
+ * Donec eget arcu bibendum nunc consequat lobortis.
+Dolor::
+ Donec eget arcu bibendum nunc consequat lobortis.
+ Suspendisse;;
+ A massa id sem aliquam auctor.
+ Morbi;;
+ Pretium nulla vel lorem.
+ In;;
+ Dictum mauris in urna.
+ Vivamus::: Fringilla mi eu lacus.
+ Donec::: Eget arcu bibendum nunc consequat lobortis.
+---------------------------------------------------------------------
+
+Which render as:
+
+In::
+Lorem::
+ Fusce euismod commodo velit.
+
+ Fusce euismod commodo velit.
+
+Ipsum:: Vivamus fringilla mi eu lacus.
+ * Vivamus fringilla mi eu lacus.
+ * Donec eget arcu bibendum nunc consequat lobortis.
+Dolor::
+ Donec eget arcu bibendum nunc consequat lobortis.
+ Suspendisse;;
+ A massa id sem aliquam auctor.
+ Morbi;;
+ Pretium nulla vel lorem.
+ In;;
+ Dictum mauris in urna.
+ Vivamus::: Fringilla mi eu lacus.
+ Donec::: Eget arcu bibendum nunc consequat lobortis.
+
+Horizontal labeled list style
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The 'horizontal' labeled list style (also the first positional
+attribute) places the list text side-by-side with the label instead of
+under the label. Here is an example:
+
+---------------------------------------------------------------------
+[horizontal]
+*Lorem*:: Fusce euismod commodo velit. Qui in magna commodo, est
+labitur dolorum an. Est ne magna primis adolescens.
+
+ Fusce euismod commodo velit.
+
+*Ipsum*:: Vivamus fringilla mi eu lacus.
+- Vivamus fringilla mi eu lacus.
+- Donec eget arcu bibendum nunc consequat lobortis.
+
+*Dolor*::
+ - Vivamus fringilla mi eu lacus.
+ - Donec eget arcu bibendum nunc consequat lobortis.
+
+---------------------------------------------------------------------
+
+Which render as:
+
+[horizontal]
+*Lorem*:: Fusce euismod commodo velit. Qui in magna commodo, est
+labitur dolorum an. Est ne magna primis adolescens.
+
+ Fusce euismod commodo velit.
+
+*Ipsum*:: Vivamus fringilla mi eu lacus.
+- Vivamus fringilla mi eu lacus.
+- Donec eget arcu bibendum nunc consequat lobortis.
+
+*Dolor*::
+ - Vivamus fringilla mi eu lacus.
+ - Donec eget arcu bibendum nunc consequat lobortis.
+
+[NOTE]
+=====================================================================
+- Current PDF toolchains do not make a good job of determining
+ the relative column widths for horizontal labeled lists.
+- Nested horizontal labeled lists will generate DocBook validation
+ errors because the 'DocBook XML V4.2' DTD does not permit nested
+ informal tables (although <> and
+ <> process them correctly).
+- The label width can be set as a percentage of the total width by
+ setting the 'width' attribute e.g. `width="10%"`
+=====================================================================
+
+Question and Answer Lists
+~~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc comes pre-configured with a 'qanda' style labeled list for generating
+DocBook question and answer (Q&A) lists. Example:
+
+---------------------------------------------------------------------
+[qanda]
+Question one::
+ Answer one.
+Question two::
+ Answer two.
+---------------------------------------------------------------------
+
+Renders:
+
+[qanda]
+Question one::
+ Answer one.
+Question two::
+ Answer two.
+
+Glossary Lists
+~~~~~~~~~~~~~~
+AsciiDoc comes pre-configured with a 'glossary' style labeled list for
+generating DocBook glossary lists. Example:
+
+---------------------------------------------------------------------
+[glossary]
+A glossary term::
+ The corresponding definition.
+A second glossary term::
+ The corresponding definition.
+---------------------------------------------------------------------
+
+For working examples see the `article.txt` and `book.txt` documents in
+the AsciiDoc `./doc` distribution directory.
+
+NOTE: To generate valid DocBook output glossary lists must be located
+in a section that uses the 'glossary' <>.
+
+Bibliography Lists
+~~~~~~~~~~~~~~~~~~
+AsciiDoc comes with a predefined 'bibliography' bulleted list style
+generating DocBook bibliography entries. Example:
+
+---------------------------------------------------------------------
+[bibliography]
+.Optional list title
+- [[[taoup]]] Eric Steven Raymond. 'The Art of UNIX
+ Programming'. Addison-Wesley. ISBN 0-13-142901-9.
+- [[[walsh-muellner]]] Norman Walsh & Leonard Muellner.
+ 'DocBook - The Definitive Guide'. O'Reilly & Associates.
+ 1999. ISBN 1-56592-580-7.
+---------------------------------------------------------------------
+
+The `[[[]]]` syntax is a bibliography entry anchor, it
+generates an anchor named `` and additionally displays
+`[]` at the anchor position. For example `[[[taoup]]]`
+generates an anchor named `taoup` that displays `[taoup]` at the
+anchor position. Cite the reference from elsewhere your document using
+`<>`, this displays a hyperlink (`[taoup]`) to the
+corresponding bibliography entry anchor.
+
+For working examples see the `article.txt` and `book.txt` documents in
+the AsciiDoc `./doc` distribution directory.
+
+NOTE: To generate valid DocBook output bibliography lists must be
+located in a <>.
+
+[[X15]]
+List Item Continuation
+~~~~~~~~~~~~~~~~~~~~~~
+Another list or a literal paragraph immediately following a list item
+is implicitly appended to the list item; to append other block
+elements to a list item you need to explicitly join them to the list
+item with a 'list continuation' (a separator line containing a single
+plus character). Multiple block elements can be appended to a list
+item using list continuations (provided they are legal list item
+children in the backend markup).
+
+Here are some examples of list item continuations: list item one
+contains multiple continuations; list item two is continued with an
+<> containing multiple elements:
+
+---------------------------------------------------------------------
+1. List item one.
++
+List item one continued with a second paragraph followed by an
+Indented block.
++
+.................
+$ ls *.sh
+$ mv *.sh ~/tmp
+.................
++
+List item continued with a third paragraph.
+
+2. List item two continued with an open block.
++
+--
+This paragraph is part of the preceding list item.
+
+a. This list is nested and does not require explicit item continuation.
++
+This paragraph is part of the preceding list item.
+
+b. List item b.
+
+This paragraph belongs to item two of the outer list.
+--
+---------------------------------------------------------------------
+
+Renders:
+
+1. List item one.
++
+List item one continued with a second paragraph followed by an
+Indented block.
++
+.................
+$ ls *.sh
+$ mv *.sh ~/tmp
+.................
++
+List item continued with a third paragraph.
+
+2. List item two continued with an open block.
++
+--
+This paragraph is part of the preceding list item.
+
+a. This list is nested and does not require explicit item continuation.
++
+This paragraph is part of the preceding list item.
+
+b. List item b.
+
+This paragraph belongs to item two of the outer list.
+--
+
+
+[[X92]]
+Footnotes
+---------
+The shipped AsciiDoc configuration includes three footnote inline
+macros:
+
+`footnote:[]`::
+ Generates a footnote with text ``.
+
+`footnoteref:[,]`::
+ Generates a footnote with a reference ID `` and text ``.
+
+`footnoteref:[]`::
+ Generates a reference to the footnote with ID ``.
+
+The footnote text can span multiple lines.
+
+The 'xhtml11' and 'html5' backends render footnotes dynamically using
+JavaScript; 'html4' outputs do not use JavaScript and leave the
+footnotes inline; 'docbook' footnotes are processed by the downstream
+DocBook toolchain.
+
+Example footnotes:
+
+ A footnote footnote:[An example footnote.];
+ a second footnote with a reference ID footnoteref:[note2,Second footnote.];
+ finally a reference to the second footnote footnoteref:[note2].
+
+Renders:
+
+A footnote footnote:[An example footnote.];
+a second footnote with a reference ID footnoteref:[note2,Second footnote.];
+finally a reference to the second footnote footnoteref:[note2].
+
+
+Indexes
+-------
+The shipped AsciiDoc configuration includes the inline macros for
+generating DocBook index entries.
+
+`indexterm:[,,]`::
+`(((,,)))`::
+ This inline macro generates an index term (the `` and
+ `` positional attributes are optional). Example:
+ `indexterm:[Tigers,Big cats]` (or, using the alternative syntax
+ `(((Tigers,Big cats)))`. Index terms that have secondary and
+ tertiary entries also generate separate index terms for the
+ secondary and tertiary entries. The index terms appear in the
+ index, not the primary text flow.
+
+`indexterm2:[]`::
+`(())`::
+ This inline macro generates an index term that appears in both the
+ index and the primary text flow. The `` should not be
+ padded to the left or right with white space characters.
+
+For working examples see the `article.txt` and `book.txt` documents in
+the AsciiDoc `./doc` distribution directory.
+
+NOTE: Index entries only really make sense if you are generating
+DocBook markup -- DocBook conversion programs automatically generate
+an index at the point an 'Index' section appears in source document.
+
+
+[[X105]]
+Callouts
+--------
+Callouts are a mechanism for annotating verbatim text (for example:
+source code, computer output and user input). Callout markers are
+placed inside the annotated text while the actual annotations are
+presented in a callout list after the annotated text. Here's an
+example:
+
+---------------------------------------------------------------------
+ .MS-DOS directory listing
+ -----------------------------------------------------
+ 10/17/97 9:04 bin
+ 10/16/97 14:11 DOS \<1>
+ 10/16/97 14:40 Program Files
+ 10/16/97 14:46 TEMP
+ 10/17/97 9:04 tmp
+ 10/16/97 14:37 WINNT
+ 10/16/97 14:25 119 AUTOEXEC.BAT \<2>
+ 2/13/94 6:21 54,619 COMMAND.COM \<2>
+ 10/16/97 14:25 115 CONFIG.SYS \<2>
+ 11/16/97 17:17 61,865,984 pagefile.sys
+ 2/13/94 6:21 9,349 WINA20.386 \<3>
+ -----------------------------------------------------
+
+ \<1> This directory holds MS-DOS.
+ \<2> System startup code for DOS.
+ \<3> Some sort of Windows 3.1 hack.
+---------------------------------------------------------------------
+
+Which renders:
+
+.MS-DOS directory listing
+-----------------------------------------------------
+10/17/97 9:04 bin
+10/16/97 14:11 DOS <1>
+10/16/97 14:40 Program Files
+10/16/97 14:46 TEMP
+10/17/97 9:04 tmp
+10/16/97 14:37 WINNT
+10/16/97 14:25 119 AUTOEXEC.BAT <2>
+ 2/13/94 6:21 54,619 COMMAND.COM <2>
+10/16/97 14:25 115 CONFIG.SYS <2>
+11/16/97 17:17 61,865,984 pagefile.sys
+ 2/13/94 6:21 9,349 WINA20.386 <3>
+-----------------------------------------------------
+
+<1> This directory holds MS-DOS.
+<2> System startup code for DOS.
+<3> Some sort of Windows 3.1 hack.
+
+.Explanation
+- The callout marks are whole numbers enclosed in angle brackets --
+ they refer to the correspondingly numbered item in the following
+ callout list.
+- By default callout marks are confined to 'LiteralParagraphs',
+ 'LiteralBlocks' and 'ListingBlocks' (although this is a
+ configuration file option and can be changed).
+- Callout list item numbering is fairly relaxed -- list items can
+ start with ``, `n>` or `>` where `n` is the optional list item
+ number (in the latter case list items starting with a single `>`
+ character are implicitly numbered starting at one).
+- Callout lists should not be nested.
+- Callout lists start list items hard against the left margin.
+- If you want to present a number inside angle brackets you'll need to
+ escape it with a backslash to prevent it being interpreted as a
+ callout mark.
+
+NOTE: Define the AsciiDoc 'icons' attribute (for example using the `-a
+icons` command-line option) to display callout icons.
+
+Implementation Notes
+~~~~~~~~~~~~~~~~~~~~
+Callout marks are generated by the 'callout' inline macro while
+callout lists are generated using the 'callout' list definition. The
+'callout' macro and 'callout' list are special in that they work
+together. The 'callout' inline macro is not enabled by the normal
+'macros' substitutions option, instead it has its own 'callouts'
+substitution option.
+
+The following attributes are available during inline callout macro
+substitution:
+
+`{index}`::
+ The callout list item index inside the angle brackets.
+`{coid}`::
+ An identifier formatted like `CO-` that
+ uniquely identifies the callout mark. For example `CO2-4`
+ identifies the fourth callout mark in the second set of callout
+ marks.
+
+The `{coids}` attribute can be used during callout list item
+substitution -- it is a space delimited list of callout IDs that refer
+to the explanatory list item.
+
+Including callouts in included code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You can annotate working code examples with callouts -- just remember
+to put the callouts inside source code comments. This example displays
+the `test.py` source file (containing a single callout) using the
+'source' (code highlighter) filter:
+
+.AsciiDoc source
+---------------------------------------------------------------------
+ [source,python]
+ -------------------------------------------
+ \include::test.py[]
+ -------------------------------------------
+
+ \<1> Print statement.
+---------------------------------------------------------------------
+
+.Included `test.py` source
+---------------------------------------------------------------------
+print 'Hello World!' # \<1>
+---------------------------------------------------------------------
+
+
+Macros
+------
+Macros are a mechanism for substituting parametrized text into output
+documents.
+
+Macros have a 'name', a single 'target' argument and an 'attribute
+list'. The usual syntax is `:[]` (for
+inline macros) and `::[]` (for block
+macros). Here are some examples:
+
+ http://www.docbook.org/[DocBook.org]
+ include::chapt1.txt[tabsize=2]
+ mailto:srackham@gmail.com[]
+
+.Macro behavior
+- `` is the macro name. It can only contain letters, digits or
+ dash characters and cannot start with a dash.
+- The optional `` cannot contain white space characters.
+- `` is a <> enclosed in square
+ brackets.
+- `]` characters inside attribute lists must be escaped with a
+ backslash.
+- Expansion of macro references can normally be escaped by prefixing a
+ backslash character (see the AsciiDoc 'FAQ' for examples of
+ exceptions to this rule).
+- Attribute references in block macros are expanded.
+- The substitutions performed prior to Inline macro macro expansion
+ are determined by the inline context.
+- Macros are processed in the order they appear in the configuration
+ file(s).
+- Calls to inline macros can be nested inside different inline macros
+ (an inline macro call cannot contain a nested call to itself).
+- In addition to ``, `` and `` the
+ `` and `` named groups are available to
+ <>. A macro is a passthrough macro if the
+ definition includes a `` named group.
+
+Inline Macros
+~~~~~~~~~~~~~
+Inline Macros occur in an inline element context. Predefined Inline
+macros include 'URLs', 'image' and 'link' macros.
+
+URLs
+^^^^
+'http', 'https', 'ftp', 'file', 'mailto' and 'callto' URLs are
+rendered using predefined inline macros.
+
+- If you don't need a custom link caption you can enter the 'http',
+ 'https', 'ftp', 'file' URLs and email addresses without any special
+ macro syntax.
+- If the `` is empty the URL is displayed.
+
+Here are some examples:
+
+ http://www.docbook.org/[DocBook.org]
+ http://www.docbook.org/
+ mailto:joe.bloggs@foobar.com[email Joe Bloggs]
+ joe.bloggs@foobar.com
+
+Which are rendered:
+
+http://www.docbook.org/[DocBook.org]
+
+http://www.docbook.org/
+
+mailto:joe.bloggs@foobar.com[email Joe Bloggs]
+
+joe.bloggs@foobar.com
+
+If the `` necessitates space characters use `%20`, for example
+`large%20image.png`.
+
+Internal Cross References
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Two AsciiDoc inline macros are provided for creating hypertext links
+within an AsciiDoc document. You can use either the standard macro
+syntax or the (preferred) alternative.
+
+[[X30]]
+anchor
+++++++
+Used to specify hypertext link targets:
+
+ [[,]]
+ anchor:[]
+
+The `` is a unique string that conforms to the output markup's
+anchor syntax. The optional `` is the text to be displayed
+by captionless 'xref' macros that refer to this anchor. The optional
+`` is only really useful when generating DocBook output.
+Example anchor:
+
+ [[X1]]
+
+You may have noticed that the syntax of this inline element is the
+same as that of the <>, this is no
+coincidence since they are functionally equivalent.
+
+xref
+++++
+Creates a hypertext link to a document anchor.
+
+ <<,
>>
+ xref:[
]
+
+The `` refers to an anchor ID. The optional `
` is the
+link's displayed text. Example:
+
+ <>
+
+If `
` is not specified then the displayed text is
+auto-generated:
+
+- The AsciiDoc 'xhtml11' and 'html5' backends display the ``
+ enclosed in square brackets.
+- If DocBook is produced the DocBook toolchain is responsible for the
+ displayed text which will normally be the referenced figure, table
+ or section title number followed by the element's title text.
+
+Here is an example:
+
+---------------------------------------------------------------------
+[[tiger_image]]
+.Tyger tyger
+image::tiger.png[]
+
+This can be seen in <>.
+---------------------------------------------------------------------
+
+Linking to Local Documents
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+Hypertext links to files on the local file system are specified using
+the 'link' inline macro.
+
+ link:[
]
+
+The 'link' macro generates relative URLs. The link macro `` is
+the target file name (relative to the file system location of the
+referring document). The optional `
` is the link's displayed
+text. If `
` is not specified then `` is displayed.
+Example:
+
+ link:downloads/foo.zip[download foo.zip]
+
+You can use the `#` syntax to refer to an anchor within
+a target document but this usually only makes sense when targeting
+HTML documents.
+
+[[X9]]
+Images
+^^^^^^
+Inline images are inserted into the output document using the 'image'
+macro. The inline syntax is:
+
+ image:[]
+
+The contents of the image file `` is displayed. To display the
+image its file format must be supported by the target backend
+application. HTML and DocBook applications normally support PNG or JPG
+files.
+
+`` file name paths are relative to the location of the
+referring document.
+
+[[X55]]
+.Image macro attributes
+- The optional 'alt' attribute is also the first positional attribute,
+ it specifies alternative text which is displayed if the output
+ application is unable to display the image file (see also
+ http://htmlhelp.com/feature/art3.htm[Use of ALT texts in IMGs]). For
+ example:
+
+ image:images/logo.png[Company Logo]
+
+- The optional 'title' attribute provides a title for the image. The
+ <> renders the title alongside the image.
+ The inline image macro displays the title as a popup ``tooltip'' in
+ visual browsers (AsciiDoc HTML outputs only).
+
+- The optional `width` and `height` attributes scale the image size
+ and can be used in any combination. The units are pixels. The
+ following example scales the previous example to a height of 32
+ pixels:
+
+ image:images/logo.png["Company Logo",height=32]
+
+- The optional `link` attribute is used to link the image to an
+ external document. The following example links a screenshot
+ thumbnail to a full size version:
+
+ image:screen-thumbnail.png[height=32,link="screen.png"]
+
+- The optional `scaledwidth` attribute is only used in DocBook block
+ images (specifically for PDF documents). The following example
+ scales the images to 75% of the available print width:
+
+ image::images/logo.png[scaledwidth="75%",alt="Company Logo"]
+
+- The image `scale` attribute sets the DocBook `imagedata` element
+ `scale` attribute.
+
+- The optional `align` attribute is used for horizontal image
+ alignment. Allowed values are `center`, `left` and `right`. For
+ example:
+
+ image::images/tiger.png["Tiger image",align="left"]
+
+- The optional `float` attribute floats the image `left` or `right` on
+ the page (works with HTML outputs only, has no effect on DocBook
+ outputs). `float` and `align` attributes are mutually exclusive.
+ Use the `unfloat::[]` block macro to stop floating.
+
+Comment Lines
+^^^^^^^^^^^^^
+See <>.
+
+Block Macros
+~~~~~~~~~~~~
+A Block macro reference must be contained in a single line separated
+either side by a blank line or a block delimiter.
+
+Block macros behave just like Inline macros, with the following
+differences:
+
+- They occur in a block context.
+- The default syntax is `::[]` (two
+ colons, not one).
+- Markup template section names end in `-blockmacro` instead of
+ `-inlinemacro`.
+
+Block Identifier
+^^^^^^^^^^^^^^^^
+The Block Identifier macro sets the `id` attribute and has the same
+syntax as the <> since it performs
+essentially the same function -- block templates use the `id`
+attribute as a block element ID. For example:
+
+ [[X30]]
+
+This is equivalent to the `[id="X30"]` <>).
+
+[[X49]]
+Images
+^^^^^^
+The 'image' block macro is used to display images in a block context.
+The syntax is:
+
+ image::[]
+
+The block `image` macro has the same <> as it's
+<> counterpart.
+
+Block images can be titled by preceding the 'image' macro with a
+'BlockTitle'. DocBook toolchains normally number titled block images
+and optionally list them in an automatically generated 'List of
+Figures' backmatter section.
+
+This example:
+
+ .Main circuit board
+ image::images/layout.png[J14P main circuit board]
+
+is equivalent to:
+
+ image::images/layout.png["J14P main circuit board",
+ title="Main circuit board"]
+
+A title prefix that can be inserted with the `caption` attribute
+(HTML backends). For example:
+
+ .Main circuit board
+ [caption="Figure 2: "]
+ image::images/layout.png[J14P main circuit board]
+
+[[X66]]
+.Embedding images in XHTML documents
+*********************************************************************
+If you define the `data-uri` attribute then images will be embedded in
+XHTML outputs using the
+http://en.wikipedia.org/wiki/Data:_URI_scheme[data URI scheme]. You
+can use the 'data-uri' attribute with the 'xhtml11' and 'html5'
+backends to produce single-file XHTML documents with embedded images
+and CSS, for example:
+
+ $ asciidoc -a data-uri mydocument.txt
+
+[NOTE]
+======
+- All current popular browsers support data URIs, although versions
+ of Internet Explorer prior to version 8 do not.
+- Some browsers limit the size of data URIs.
+======
+*********************************************************************
+
+[[X25]]
+Comment Lines
+^^^^^^^^^^^^^
+Single lines starting with two forward slashes hard up against the
+left margin are treated as comments. Comment lines do not appear in
+the output unless the 'showcomments' attribute is defined. Comment
+lines have been implemented as both block and inline macros so a
+comment line can appear as a stand-alone block or within block elements
+that support inline macro expansion. Example comment line:
+
+ // This is a comment.
+
+If the 'showcomments' attribute is defined comment lines are written
+to the output:
+
+- In DocBook the comment lines are enclosed by the 'remark' element
+ (which may or may not be rendered by your toolchain).
+- The 'showcomments' attribute does not expose <>.
+ Comment Blocks are never passed to the output.
+
+System Macros
+~~~~~~~~~~~~~
+System macros are block macros that perform a predefined task and are
+hardwired into the asciidoc(1) program.
+
+- You can escape system macros with a leading backslash character
+ (as you can with other macros).
+- The syntax and tasks performed by system macros is built into
+ asciidoc(1) so they don't appear in configuration files. You can
+ however customize the syntax by adding entries to a configuration
+ file `[macros]` section.
+
+[[X63]]
+Include Macros
+^^^^^^^^^^^^^^
+The `include` and `include1` system macros to include the contents of
+a named file into the source document.
+
+The `include` macro includes a file as if it were part of the parent
+document -- tabs are expanded and system macros processed. The
+contents of `include1` files are not subject to tab expansion or
+system macro processing nor are attribute or lower priority
+substitutions performed. The `include1` macro's intended use is to
+include verbatim embedded CSS or scripts into configuration file
+headers. Example:
+
+------------------------------------
+\include::chapter1.txt[tabsize=4]
+------------------------------------
+
+.Include macro behavior
+- If the included file name is specified with a relative path then the
+ path is relative to the location of the referring document.
+- Include macros can appear inside configuration files.
+- Files included from within 'DelimitedBlocks' are read to completion
+ to avoid false end-of-block underline termination.
+- Attribute references are expanded inside the include 'target'; if an
+ attribute is undefined then the included file is silently skipped.
+- The 'tabsize' macro attribute sets the number of space characters to
+ be used for tab expansion in the included file (not applicable to
+ `include1` macro).
+- The 'depth' macro attribute sets the maximum permitted number of
+ subsequent nested includes (not applicable to `include1` macro which
+ does not process nested includes). Setting 'depth' to '1' disables
+ nesting inside the included file. By default, nesting is limited to
+ a depth of ten.
+- If the he 'warnings' attribute is set to 'False' (or any other
+ Python literal that evaluates to boolean false) then no warning
+ message is printed if the included file does not exist. By default
+ 'warnings' are enabled.
+- Internally the `include1` macro is translated to the `include1`
+ system attribute which means it must be evaluated in a region where
+ attribute substitution is enabled. To inhibit nested substitution in
+ included files it is preferable to use the `include` macro and set
+ the attribute `depth=1`.
+
+Conditional Inclusion Macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Lines of text in the source document can be selectively included or
+excluded from processing based on the existence (or not) of a document
+attribute.
+
+Document text between the `ifdef` and `endif` macros is included if a
+document attribute is defined:
+
+ ifdef::[]
+ :
+ endif::[]
+
+Document text between the `ifndef` and `endif` macros is not included
+if a document attribute is defined:
+
+ ifndef::[]
+ :
+ endif::[]
+
+`` is an attribute name which is optional in the trailing
+`endif` macro.
+
+If you only want to process a single line of text then the text can be
+put inside the square brackets and the `endif` macro omitted, for
+example:
+
+ ifdef::revnumber[Version number 42]
+
+Is equivalent to:
+
+ ifdef::revnumber[]
+ Version number 42
+ endif::revnumber[]
+
+'ifdef' and 'ifndef' macros also accept multiple attribute names:
+
+- Multiple ',' separated attribute names evaluate to defined if one
+ or more of the attributes is defined, otherwise it's value is
+ undefined.
+- Multiple '+' separated attribute names evaluate to defined if all
+ of the attributes is defined, otherwise it's value is undefined.
+
+Document text between the `ifeval` and `endif` macros is included if
+the Python expression inside the square brackets is true. Example:
+
+ ifeval::[{rs458}==2]
+ :
+ endif::[]
+
+- Document attribute references are expanded before the expression is
+ evaluated.
+- If an attribute reference is undefined then the expression is
+ considered false.
+
+Take a look at the `*.conf` configuration files in the AsciiDoc
+distribution for examples of conditional inclusion macro usage.
+
+Executable system macros
+^^^^^^^^^^^^^^^^^^^^^^^^
+The 'eval', 'sys' and 'sys2' block macros exhibit the same behavior as
+their same named <>. The difference
+is that system macros occur in a block macro context whereas system
+attributes are confined to inline contexts where attribute
+substitution is enabled.
+
+The following example displays a long directory listing inside a
+literal block:
+
+ ------------------
+ sys::[ls -l *.txt]
+ ------------------
+
+NOTE: There are no block macro versions of the 'eval3' and 'sys3'
+system attributes.
+
+Template System Macro
+^^^^^^^^^^^^^^^^^^^^^
+The `template` block macro allows the inclusion of one configuration
+file template section within another. The following example includes
+the `[admonitionblock]` section in the `[admonitionparagraph]`
+section:
+
+ [admonitionparagraph]
+ template::[admonitionblock]
+
+.Template macro behavior
+- The `template::[]` macro is useful for factoring configuration file
+ markup.
+- `template::[]` macros cannot be nested.
+- `template::[]` macro expansion is applied after all configuration
+ files have been read.
+
+
+[[X77]]
+Passthrough macros
+~~~~~~~~~~~~~~~~~~
+Passthrough macros are analogous to <> and are
+used to pass text directly to the output. The substitution performed
+on the text is determined by the macro definition but can be overridden
+by the ``. The usual syntax is
+`