UNPKG

707 kBJavaScriptView Raw
1/*!
2 * fei-editor v0.0.2
3 * (c) 2023 yangmengfei
4 * @license MIT
5 */
6'use strict';
7
8Object.defineProperty(exports, '__esModule', { value: true });
9
10var vue = require('vue');
11
12/* ***** BEGIN LICENSE BLOCK *****
13 * Distributed under the BSD license:
14 *
15 * Copyright (c) 2010, Ajax.org B.V.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 * * Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * * Neither the name of Ajax.org B.V. nor the
26 * names of its contributors may be used to endorse or promote products
27 * derived from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * ***** END LICENSE BLOCK ***** */
41
42/**
43 * Define a module along with a payload
44 * @param module a name for the payload
45 * @param payload a function to call with (acequire, exports, module) params
46 */
47
48(function() {
49
50var ACE_NAMESPACE = "ace";
51
52var global = (function() { return this; })();
53if (!global && typeof window != "undefined") global = window; // strict mode
54
55
56var define = function(module, deps, payload) {
57 if (typeof module !== "string") {
58 if (define.original)
59 define.original.apply(this, arguments);
60 else {
61 console.error("dropping module because define wasn\'t a string.");
62 console.trace();
63 }
64 return;
65 }
66 if (arguments.length == 2)
67 payload = deps;
68 if (!define.modules[module]) {
69 define.payloads[module] = payload;
70 define.modules[module] = null;
71 }
72};
73
74define.modules = {};
75define.payloads = {};
76
77/**
78 * Get at functionality define()ed using the function above
79 */
80var _acequire = function(parentId, module, callback) {
81 if (typeof module === "string") {
82 var payload = lookup(parentId, module);
83 if (payload != undefined) {
84 callback && callback();
85 return payload;
86 }
87 } else if (Object.prototype.toString.call(module) === "[object Array]") {
88 var params = [];
89 for (var i = 0, l = module.length; i < l; ++i) {
90 var dep = lookup(parentId, module[i]);
91 if (dep == undefined && acequire.original)
92 return;
93 params.push(dep);
94 }
95 return callback && callback.apply(null, params) || true;
96 }
97};
98
99var acequire = function(module, callback) {
100 var packagedModule = _acequire("", module, callback);
101 if (packagedModule == undefined && acequire.original)
102 return acequire.original.apply(this, arguments);
103 return packagedModule;
104};
105
106var normalizeModule = function(parentId, moduleName) {
107 // normalize plugin acequires
108 if (moduleName.indexOf("!") !== -1) {
109 var chunks = moduleName.split("!");
110 return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
111 }
112 // normalize relative acequires
113 if (moduleName.charAt(0) == ".") {
114 var base = parentId.split("/").slice(0, -1).join("/");
115 moduleName = base + "/" + moduleName;
116
117 while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
118 var previous = moduleName;
119 moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
120 }
121 }
122 return moduleName;
123};
124
125/**
126 * Internal function to lookup moduleNames and resolve them by calling the
127 * definition function if needed.
128 */
129var lookup = function(parentId, moduleName) {
130 moduleName = normalizeModule(parentId, moduleName);
131
132 var module = define.modules[moduleName];
133 if (!module) {
134 module = define.payloads[moduleName];
135 if (typeof module === 'function') {
136 var exports = {};
137 var mod = {
138 id: moduleName,
139 uri: '',
140 exports: exports,
141 packaged: true
142 };
143
144 var req = function(module, callback) {
145 return _acequire(moduleName, module, callback);
146 };
147
148 var returnValue = module(req, exports, mod);
149 exports = returnValue || mod.exports;
150 define.modules[moduleName] = exports;
151 delete define.payloads[moduleName];
152 }
153 module = define.modules[moduleName] = exports || module;
154 }
155 return module;
156};
157
158function exportAce(ns) {
159 var root = global;
160 if (ns) {
161 if (!global[ns])
162 global[ns] = {};
163 root = global[ns];
164 }
165
166 if (!root.define || !root.define.packaged) {
167 define.original = root.define;
168 root.define = define;
169 root.define.packaged = true;
170 }
171
172 if (!root.acequire || !root.acequire.packaged) {
173 acequire.original = root.acequire;
174 root.acequire = acequire;
175 root.acequire.packaged = true;
176 }
177}
178
179exportAce(ACE_NAMESPACE);
180
181})();
182
183ace.define("ace/lib/regexp",["require","exports","module"], function(acequire, exports, module) {
184
185 var real = {
186 exec: RegExp.prototype.exec,
187 test: RegExp.prototype.test,
188 match: String.prototype.match,
189 replace: String.prototype.replace,
190 split: String.prototype.split
191 },
192 compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
193 compliantLastIndexIncrement = function () {
194 var x = /^/g;
195 real.test.call(x, "");
196 return !x.lastIndex;
197 }();
198
199 if (compliantLastIndexIncrement && compliantExecNpcg)
200 return;
201 RegExp.prototype.exec = function (str) {
202 var match = real.exec.apply(this, arguments),
203 name, r2;
204 if ( typeof(str) == 'string' && match) {
205 if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
206 r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
207 real.replace.call(str.slice(match.index), r2, function () {
208 for (var i = 1; i < arguments.length - 2; i++) {
209 if (arguments[i] === undefined)
210 match[i] = undefined;
211 }
212 });
213 }
214 if (this._xregexp && this._xregexp.captureNames) {
215 for (var i = 1; i < match.length; i++) {
216 name = this._xregexp.captureNames[i - 1];
217 if (name)
218 match[name] = match[i];
219 }
220 }
221 if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
222 this.lastIndex--;
223 }
224 return match;
225 };
226 if (!compliantLastIndexIncrement) {
227 RegExp.prototype.test = function (str) {
228 var match = real.exec.call(this, str);
229 if (match && this.global && !match[0].length && (this.lastIndex > match.index))
230 this.lastIndex--;
231 return !!match;
232 };
233 }
234
235 function getNativeFlags (regex) {
236 return (regex.global ? "g" : "") +
237 (regex.ignoreCase ? "i" : "") +
238 (regex.multiline ? "m" : "") +
239 (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3
240 (regex.sticky ? "y" : "");
241 }
242
243 function indexOf (array, item, from) {
244 if (Array.prototype.indexOf) // Use the native array method if available
245 return array.indexOf(item, from);
246 for (var i = from || 0; i < array.length; i++) {
247 if (array[i] === item)
248 return i;
249 }
250 return -1;
251 }
252
253});
254
255ace.define("ace/lib/es5-shim",["require","exports","module"], function(acequire, exports, module) {
256
257function Empty() {}
258
259if (!Function.prototype.bind) {
260 Function.prototype.bind = function bind(that) { // .length is 1
261 var target = this;
262 if (typeof target != "function") {
263 throw new TypeError("Function.prototype.bind called on incompatible " + target);
264 }
265 var args = slice.call(arguments, 1); // for normal call
266 var bound = function () {
267
268 if (this instanceof bound) {
269
270 var result = target.apply(
271 this,
272 args.concat(slice.call(arguments))
273 );
274 if (Object(result) === result) {
275 return result;
276 }
277 return this;
278
279 } else {
280 return target.apply(
281 that,
282 args.concat(slice.call(arguments))
283 );
284
285 }
286
287 };
288 if(target.prototype) {
289 Empty.prototype = target.prototype;
290 bound.prototype = new Empty();
291 Empty.prototype = null;
292 }
293 return bound;
294 };
295}
296var call = Function.prototype.call;
297var prototypeOfArray = Array.prototype;
298var prototypeOfObject = Object.prototype;
299var slice = prototypeOfArray.slice;
300var _toString = call.bind(prototypeOfObject.toString);
301var owns = call.bind(prototypeOfObject.hasOwnProperty);
302var defineGetter;
303var defineSetter;
304var lookupGetter;
305var lookupSetter;
306var supportsAccessors;
307if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
308 defineGetter = call.bind(prototypeOfObject.__defineGetter__);
309 defineSetter = call.bind(prototypeOfObject.__defineSetter__);
310 lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
311 lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
312}
313if ([1,2].splice(0).length != 2) {
314 if(function() { // test IE < 9 to splice bug - see issue #138
315 function makeArray(l) {
316 var a = new Array(l+2);
317 a[0] = a[1] = 0;
318 return a;
319 }
320 var array = [], lengthBefore;
321
322 array.splice.apply(array, makeArray(20));
323 array.splice.apply(array, makeArray(26));
324
325 lengthBefore = array.length; //46
326 array.splice(5, 0, "XXX"); // add one element
327
328 if (lengthBefore + 1 == array.length) {
329 return true;// has right splice implementation without bugs
330 }
331 }()) {//IE 6/7
332 var array_splice = Array.prototype.splice;
333 Array.prototype.splice = function(start, deleteCount) {
334 if (!arguments.length) {
335 return [];
336 } else {
337 return array_splice.apply(this, [
338 start === void 0 ? 0 : start,
339 deleteCount === void 0 ? (this.length - start) : deleteCount
340 ].concat(slice.call(arguments, 2)))
341 }
342 };
343 } else {//IE8
344 Array.prototype.splice = function(pos, removeCount){
345 var length = this.length;
346 if (pos > 0) {
347 if (pos > length)
348 pos = length;
349 } else if (pos == void 0) {
350 pos = 0;
351 } else if (pos < 0) {
352 pos = Math.max(length + pos, 0);
353 }
354
355 if (!(pos+removeCount < length))
356 removeCount = length - pos;
357
358 var removed = this.slice(pos, pos+removeCount);
359 var insert = slice.call(arguments, 2);
360 var add = insert.length;
361 if (pos === length) {
362 if (add) {
363 this.push.apply(this, insert);
364 }
365 } else {
366 var remove = Math.min(removeCount, length - pos);
367 var tailOldPos = pos + remove;
368 var tailNewPos = tailOldPos + add - remove;
369 var tailCount = length - tailOldPos;
370 var lengthAfterRemove = length - remove;
371
372 if (tailNewPos < tailOldPos) { // case A
373 for (var i = 0; i < tailCount; ++i) {
374 this[tailNewPos+i] = this[tailOldPos+i];
375 }
376 } else if (tailNewPos > tailOldPos) { // case B
377 for (i = tailCount; i--; ) {
378 this[tailNewPos+i] = this[tailOldPos+i];
379 }
380 } // else, add == remove (nothing to do)
381
382 if (add && pos === lengthAfterRemove) {
383 this.length = lengthAfterRemove; // truncate array
384 this.push.apply(this, insert);
385 } else {
386 this.length = lengthAfterRemove + add; // reserves space
387 for (i = 0; i < add; ++i) {
388 this[pos+i] = insert[i];
389 }
390 }
391 }
392 return removed;
393 };
394 }
395}
396if (!Array.isArray) {
397 Array.isArray = function isArray(obj) {
398 return _toString(obj) == "[object Array]";
399 };
400}
401var boxedString = Object("a"),
402 splitString = boxedString[0] != "a" || !(0 in boxedString);
403
404if (!Array.prototype.forEach) {
405 Array.prototype.forEach = function forEach(fun /*, thisp*/) {
406 var object = toObject(this),
407 self = splitString && _toString(this) == "[object String]" ?
408 this.split("") :
409 object,
410 thisp = arguments[1],
411 i = -1,
412 length = self.length >>> 0;
413 if (_toString(fun) != "[object Function]") {
414 throw new TypeError(); // TODO message
415 }
416
417 while (++i < length) {
418 if (i in self) {
419 fun.call(thisp, self[i], i, object);
420 }
421 }
422 };
423}
424if (!Array.prototype.map) {
425 Array.prototype.map = function map(fun /*, thisp*/) {
426 var object = toObject(this),
427 self = splitString && _toString(this) == "[object String]" ?
428 this.split("") :
429 object,
430 length = self.length >>> 0,
431 result = Array(length),
432 thisp = arguments[1];
433 if (_toString(fun) != "[object Function]") {
434 throw new TypeError(fun + " is not a function");
435 }
436
437 for (var i = 0; i < length; i++) {
438 if (i in self)
439 result[i] = fun.call(thisp, self[i], i, object);
440 }
441 return result;
442 };
443}
444if (!Array.prototype.filter) {
445 Array.prototype.filter = function filter(fun /*, thisp */) {
446 var object = toObject(this),
447 self = splitString && _toString(this) == "[object String]" ?
448 this.split("") :
449 object,
450 length = self.length >>> 0,
451 result = [],
452 value,
453 thisp = arguments[1];
454 if (_toString(fun) != "[object Function]") {
455 throw new TypeError(fun + " is not a function");
456 }
457
458 for (var i = 0; i < length; i++) {
459 if (i in self) {
460 value = self[i];
461 if (fun.call(thisp, value, i, object)) {
462 result.push(value);
463 }
464 }
465 }
466 return result;
467 };
468}
469if (!Array.prototype.every) {
470 Array.prototype.every = function every(fun /*, thisp */) {
471 var object = toObject(this),
472 self = splitString && _toString(this) == "[object String]" ?
473 this.split("") :
474 object,
475 length = self.length >>> 0,
476 thisp = arguments[1];
477 if (_toString(fun) != "[object Function]") {
478 throw new TypeError(fun + " is not a function");
479 }
480
481 for (var i = 0; i < length; i++) {
482 if (i in self && !fun.call(thisp, self[i], i, object)) {
483 return false;
484 }
485 }
486 return true;
487 };
488}
489if (!Array.prototype.some) {
490 Array.prototype.some = function some(fun /*, thisp */) {
491 var object = toObject(this),
492 self = splitString && _toString(this) == "[object String]" ?
493 this.split("") :
494 object,
495 length = self.length >>> 0,
496 thisp = arguments[1];
497 if (_toString(fun) != "[object Function]") {
498 throw new TypeError(fun + " is not a function");
499 }
500
501 for (var i = 0; i < length; i++) {
502 if (i in self && fun.call(thisp, self[i], i, object)) {
503 return true;
504 }
505 }
506 return false;
507 };
508}
509if (!Array.prototype.reduce) {
510 Array.prototype.reduce = function reduce(fun /*, initial*/) {
511 var object = toObject(this),
512 self = splitString && _toString(this) == "[object String]" ?
513 this.split("") :
514 object,
515 length = self.length >>> 0;
516 if (_toString(fun) != "[object Function]") {
517 throw new TypeError(fun + " is not a function");
518 }
519 if (!length && arguments.length == 1) {
520 throw new TypeError("reduce of empty array with no initial value");
521 }
522
523 var i = 0;
524 var result;
525 if (arguments.length >= 2) {
526 result = arguments[1];
527 } else {
528 do {
529 if (i in self) {
530 result = self[i++];
531 break;
532 }
533 if (++i >= length) {
534 throw new TypeError("reduce of empty array with no initial value");
535 }
536 } while (true);
537 }
538
539 for (; i < length; i++) {
540 if (i in self) {
541 result = fun.call(void 0, result, self[i], i, object);
542 }
543 }
544
545 return result;
546 };
547}
548if (!Array.prototype.reduceRight) {
549 Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
550 var object = toObject(this),
551 self = splitString && _toString(this) == "[object String]" ?
552 this.split("") :
553 object,
554 length = self.length >>> 0;
555 if (_toString(fun) != "[object Function]") {
556 throw new TypeError(fun + " is not a function");
557 }
558 if (!length && arguments.length == 1) {
559 throw new TypeError("reduceRight of empty array with no initial value");
560 }
561
562 var result, i = length - 1;
563 if (arguments.length >= 2) {
564 result = arguments[1];
565 } else {
566 do {
567 if (i in self) {
568 result = self[i--];
569 break;
570 }
571 if (--i < 0) {
572 throw new TypeError("reduceRight of empty array with no initial value");
573 }
574 } while (true);
575 }
576
577 do {
578 if (i in this) {
579 result = fun.call(void 0, result, self[i], i, object);
580 }
581 } while (i--);
582
583 return result;
584 };
585}
586if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
587 Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
588 var self = splitString && _toString(this) == "[object String]" ?
589 this.split("") :
590 toObject(this),
591 length = self.length >>> 0;
592
593 if (!length) {
594 return -1;
595 }
596
597 var i = 0;
598 if (arguments.length > 1) {
599 i = toInteger(arguments[1]);
600 }
601 i = i >= 0 ? i : Math.max(0, length + i);
602 for (; i < length; i++) {
603 if (i in self && self[i] === sought) {
604 return i;
605 }
606 }
607 return -1;
608 };
609}
610if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
611 Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
612 var self = splitString && _toString(this) == "[object String]" ?
613 this.split("") :
614 toObject(this),
615 length = self.length >>> 0;
616
617 if (!length) {
618 return -1;
619 }
620 var i = length - 1;
621 if (arguments.length > 1) {
622 i = Math.min(i, toInteger(arguments[1]));
623 }
624 i = i >= 0 ? i : length - Math.abs(i);
625 for (; i >= 0; i--) {
626 if (i in self && sought === self[i]) {
627 return i;
628 }
629 }
630 return -1;
631 };
632}
633if (!Object.getPrototypeOf) {
634 Object.getPrototypeOf = function getPrototypeOf(object) {
635 return object.__proto__ || (
636 object.constructor ?
637 object.constructor.prototype :
638 prototypeOfObject
639 );
640 };
641}
642if (!Object.getOwnPropertyDescriptor) {
643 var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
644 "non-object: ";
645 Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
646 if ((typeof object != "object" && typeof object != "function") || object === null)
647 throw new TypeError(ERR_NON_OBJECT + object);
648 if (!owns(object, property))
649 return;
650
651 var descriptor, getter, setter;
652 descriptor = { enumerable: true, configurable: true };
653 if (supportsAccessors) {
654 var prototype = object.__proto__;
655 object.__proto__ = prototypeOfObject;
656
657 var getter = lookupGetter(object, property);
658 var setter = lookupSetter(object, property);
659 object.__proto__ = prototype;
660
661 if (getter || setter) {
662 if (getter) descriptor.get = getter;
663 if (setter) descriptor.set = setter;
664 return descriptor;
665 }
666 }
667 descriptor.value = object[property];
668 return descriptor;
669 };
670}
671if (!Object.getOwnPropertyNames) {
672 Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
673 return Object.keys(object);
674 };
675}
676if (!Object.create) {
677 var createEmpty;
678 if (Object.prototype.__proto__ === null) {
679 createEmpty = function () {
680 return { "__proto__": null };
681 };
682 } else {
683 createEmpty = function () {
684 var empty = {};
685 for (var i in empty)
686 empty[i] = null;
687 empty.constructor =
688 empty.hasOwnProperty =
689 empty.propertyIsEnumerable =
690 empty.isPrototypeOf =
691 empty.toLocaleString =
692 empty.toString =
693 empty.valueOf =
694 empty.__proto__ = null;
695 return empty;
696 };
697 }
698
699 Object.create = function create(prototype, properties) {
700 var object;
701 if (prototype === null) {
702 object = createEmpty();
703 } else {
704 if (typeof prototype != "object")
705 throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
706 var Type = function () {};
707 Type.prototype = prototype;
708 object = new Type();
709 object.__proto__ = prototype;
710 }
711 if (properties !== void 0)
712 Object.defineProperties(object, properties);
713 return object;
714 };
715}
716
717function doesDefinePropertyWork(object) {
718 try {
719 Object.defineProperty(object, "sentinel", {});
720 return "sentinel" in object;
721 } catch (exception) {
722 }
723}
724if (Object.defineProperty) {
725 var definePropertyWorksOnObject = doesDefinePropertyWork({});
726 var definePropertyWorksOnDom = typeof document == "undefined" ||
727 doesDefinePropertyWork(document.createElement("div"));
728 if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
729 var definePropertyFallback = Object.defineProperty;
730 }
731}
732
733if (!Object.defineProperty || definePropertyFallback) {
734 var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
735 var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: ";
736 var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
737 "on this javascript engine";
738
739 Object.defineProperty = function defineProperty(object, property, descriptor) {
740 if ((typeof object != "object" && typeof object != "function") || object === null)
741 throw new TypeError(ERR_NON_OBJECT_TARGET + object);
742 if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
743 throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
744 if (definePropertyFallback) {
745 try {
746 return definePropertyFallback.call(Object, object, property, descriptor);
747 } catch (exception) {
748 }
749 }
750 if (owns(descriptor, "value")) {
751
752 if (supportsAccessors && (lookupGetter(object, property) ||
753 lookupSetter(object, property)))
754 {
755 var prototype = object.__proto__;
756 object.__proto__ = prototypeOfObject;
757 delete object[property];
758 object[property] = descriptor.value;
759 object.__proto__ = prototype;
760 } else {
761 object[property] = descriptor.value;
762 }
763 } else {
764 if (!supportsAccessors)
765 throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
766 if (owns(descriptor, "get"))
767 defineGetter(object, property, descriptor.get);
768 if (owns(descriptor, "set"))
769 defineSetter(object, property, descriptor.set);
770 }
771
772 return object;
773 };
774}
775if (!Object.defineProperties) {
776 Object.defineProperties = function defineProperties(object, properties) {
777 for (var property in properties) {
778 if (owns(properties, property))
779 Object.defineProperty(object, property, properties[property]);
780 }
781 return object;
782 };
783}
784if (!Object.seal) {
785 Object.seal = function seal(object) {
786 return object;
787 };
788}
789if (!Object.freeze) {
790 Object.freeze = function freeze(object) {
791 return object;
792 };
793}
794try {
795 Object.freeze(function () {});
796} catch (exception) {
797 Object.freeze = (function freeze(freezeObject) {
798 return function freeze(object) {
799 if (typeof object == "function") {
800 return object;
801 } else {
802 return freezeObject(object);
803 }
804 };
805 })(Object.freeze);
806}
807if (!Object.preventExtensions) {
808 Object.preventExtensions = function preventExtensions(object) {
809 return object;
810 };
811}
812if (!Object.isSealed) {
813 Object.isSealed = function isSealed(object) {
814 return false;
815 };
816}
817if (!Object.isFrozen) {
818 Object.isFrozen = function isFrozen(object) {
819 return false;
820 };
821}
822if (!Object.isExtensible) {
823 Object.isExtensible = function isExtensible(object) {
824 if (Object(object) === object) {
825 throw new TypeError(); // TODO message
826 }
827 var name = '';
828 while (owns(object, name)) {
829 name += '?';
830 }
831 object[name] = true;
832 var returnValue = owns(object, name);
833 delete object[name];
834 return returnValue;
835 };
836}
837if (!Object.keys) {
838 var hasDontEnumBug = true,
839 dontEnums = [
840 "toString",
841 "toLocaleString",
842 "valueOf",
843 "hasOwnProperty",
844 "isPrototypeOf",
845 "propertyIsEnumerable",
846 "constructor"
847 ],
848 dontEnumsLength = dontEnums.length;
849
850 for (var key in {"toString": null}) {
851 hasDontEnumBug = false;
852 }
853
854 Object.keys = function keys(object) {
855
856 if (
857 (typeof object != "object" && typeof object != "function") ||
858 object === null
859 ) {
860 throw new TypeError("Object.keys called on a non-object");
861 }
862
863 var keys = [];
864 for (var name in object) {
865 if (owns(object, name)) {
866 keys.push(name);
867 }
868 }
869
870 if (hasDontEnumBug) {
871 for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
872 var dontEnum = dontEnums[i];
873 if (owns(object, dontEnum)) {
874 keys.push(dontEnum);
875 }
876 }
877 }
878 return keys;
879 };
880
881}
882if (!Date.now) {
883 Date.now = function now() {
884 return new Date().getTime();
885 };
886}
887var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
888 "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
889 "\u2029\uFEFF";
890if (!String.prototype.trim || ws.trim()) {
891 ws = "[" + ws + "]";
892 var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
893 trimEndRegexp = new RegExp(ws + ws + "*$");
894 String.prototype.trim = function trim() {
895 return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
896 };
897}
898
899function toInteger(n) {
900 n = +n;
901 if (n !== n) { // isNaN
902 n = 0;
903 } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
904 n = (n > 0 || -1) * Math.floor(Math.abs(n));
905 }
906 return n;
907}
908var toObject = function (o) {
909 if (o == null) { // this matches both null and undefined
910 throw new TypeError("can't convert "+o+" to object");
911 }
912 return Object(o);
913};
914
915});
916
917ace.define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(acequire, exports, module) {
918
919acequire("./regexp");
920acequire("./es5-shim");
921
922});
923
924ace.define("ace/lib/dom",["require","exports","module"], function(acequire, exports, module) {
925
926var XHTML_NS = "http://www.w3.org/1999/xhtml";
927
928exports.getDocumentHead = function(doc) {
929 if (!doc)
930 doc = document;
931 return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
932};
933
934exports.createElement = function(tag, ns) {
935 return document.createElementNS ?
936 document.createElementNS(ns || XHTML_NS, tag) :
937 document.createElement(tag);
938};
939
940exports.hasCssClass = function(el, name) {
941 var classes = (el.className + "").split(/\s+/g);
942 return classes.indexOf(name) !== -1;
943};
944exports.addCssClass = function(el, name) {
945 if (!exports.hasCssClass(el, name)) {
946 el.className += " " + name;
947 }
948};
949exports.removeCssClass = function(el, name) {
950 var classes = el.className.split(/\s+/g);
951 while (true) {
952 var index = classes.indexOf(name);
953 if (index == -1) {
954 break;
955 }
956 classes.splice(index, 1);
957 }
958 el.className = classes.join(" ");
959};
960
961exports.toggleCssClass = function(el, name) {
962 var classes = el.className.split(/\s+/g), add = true;
963 while (true) {
964 var index = classes.indexOf(name);
965 if (index == -1) {
966 break;
967 }
968 add = false;
969 classes.splice(index, 1);
970 }
971 if (add)
972 classes.push(name);
973
974 el.className = classes.join(" ");
975 return add;
976};
977exports.setCssClass = function(node, className, include) {
978 if (include) {
979 exports.addCssClass(node, className);
980 } else {
981 exports.removeCssClass(node, className);
982 }
983};
984
985exports.hasCssString = function(id, doc) {
986 var index = 0, sheets;
987 doc = doc || document;
988
989 if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
990 while (index < sheets.length)
991 if (sheets[index++].owningElement.id === id) return true;
992 } else if ((sheets = doc.getElementsByTagName("style"))) {
993 while (index < sheets.length)
994 if (sheets[index++].id === id) return true;
995 }
996
997 return false;
998};
999
1000exports.importCssString = function importCssString(cssText, id, doc) {
1001 doc = doc || document;
1002 if (id && exports.hasCssString(id, doc))
1003 return null;
1004
1005 var style;
1006
1007 if (id)
1008 cssText += "\n/*# sourceURL=ace/css/" + id + " */";
1009
1010 if (doc.createStyleSheet) {
1011 style = doc.createStyleSheet();
1012 style.cssText = cssText;
1013 if (id)
1014 style.owningElement.id = id;
1015 } else {
1016 style = exports.createElement("style");
1017 style.appendChild(doc.createTextNode(cssText));
1018 if (id)
1019 style.id = id;
1020
1021 exports.getDocumentHead(doc).appendChild(style);
1022 }
1023};
1024
1025exports.importCssStylsheet = function(uri, doc) {
1026 if (doc.createStyleSheet) {
1027 doc.createStyleSheet(uri);
1028 } else {
1029 var link = exports.createElement('link');
1030 link.rel = 'stylesheet';
1031 link.href = uri;
1032
1033 exports.getDocumentHead(doc).appendChild(link);
1034 }
1035};
1036
1037exports.getInnerWidth = function(element) {
1038 return (
1039 parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
1040 parseInt(exports.computedStyle(element, "paddingRight"), 10) +
1041 element.clientWidth
1042 );
1043};
1044
1045exports.getInnerHeight = function(element) {
1046 return (
1047 parseInt(exports.computedStyle(element, "paddingTop"), 10) +
1048 parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
1049 element.clientHeight
1050 );
1051};
1052
1053exports.scrollbarWidth = function(document) {
1054 var inner = exports.createElement("ace_inner");
1055 inner.style.width = "100%";
1056 inner.style.minWidth = "0px";
1057 inner.style.height = "200px";
1058 inner.style.display = "block";
1059
1060 var outer = exports.createElement("ace_outer");
1061 var style = outer.style;
1062
1063 style.position = "absolute";
1064 style.left = "-10000px";
1065 style.overflow = "hidden";
1066 style.width = "200px";
1067 style.minWidth = "0px";
1068 style.height = "150px";
1069 style.display = "block";
1070
1071 outer.appendChild(inner);
1072
1073 var body = document.documentElement;
1074 body.appendChild(outer);
1075
1076 var noScrollbar = inner.offsetWidth;
1077
1078 style.overflow = "scroll";
1079 var withScrollbar = inner.offsetWidth;
1080
1081 if (noScrollbar == withScrollbar) {
1082 withScrollbar = outer.clientWidth;
1083 }
1084
1085 body.removeChild(outer);
1086
1087 return noScrollbar-withScrollbar;
1088};
1089
1090if (typeof document == "undefined") {
1091 exports.importCssString = function() {};
1092 return;
1093}
1094
1095if (window.pageYOffset !== undefined) {
1096 exports.getPageScrollTop = function() {
1097 return window.pageYOffset;
1098 };
1099
1100 exports.getPageScrollLeft = function() {
1101 return window.pageXOffset;
1102 };
1103}
1104else {
1105 exports.getPageScrollTop = function() {
1106 return document.body.scrollTop;
1107 };
1108
1109 exports.getPageScrollLeft = function() {
1110 return document.body.scrollLeft;
1111 };
1112}
1113
1114if (window.getComputedStyle)
1115 exports.computedStyle = function(element, style) {
1116 if (style)
1117 return (window.getComputedStyle(element, "") || {})[style] || "";
1118 return window.getComputedStyle(element, "") || {};
1119 };
1120else
1121 exports.computedStyle = function(element, style) {
1122 if (style)
1123 return element.currentStyle[style];
1124 return element.currentStyle;
1125 };
1126exports.setInnerHtml = function(el, innerHtml) {
1127 var element = el.cloneNode(false);//document.createElement("div");
1128 element.innerHTML = innerHtml;
1129 el.parentNode.replaceChild(element, el);
1130 return element;
1131};
1132
1133if ("textContent" in document.documentElement) {
1134 exports.setInnerText = function(el, innerText) {
1135 el.textContent = innerText;
1136 };
1137
1138 exports.getInnerText = function(el) {
1139 return el.textContent;
1140 };
1141}
1142else {
1143 exports.setInnerText = function(el, innerText) {
1144 el.innerText = innerText;
1145 };
1146
1147 exports.getInnerText = function(el) {
1148 return el.innerText;
1149 };
1150}
1151
1152exports.getParentWindow = function(document) {
1153 return document.defaultView || document.parentWindow;
1154};
1155
1156});
1157
1158ace.define("ace/lib/oop",["require","exports","module"], function(acequire, exports, module) {
1159
1160exports.inherits = function(ctor, superCtor) {
1161 ctor.super_ = superCtor;
1162 ctor.prototype = Object.create(superCtor.prototype, {
1163 constructor: {
1164 value: ctor,
1165 enumerable: false,
1166 writable: true,
1167 configurable: true
1168 }
1169 });
1170};
1171
1172exports.mixin = function(obj, mixin) {
1173 for (var key in mixin) {
1174 obj[key] = mixin[key];
1175 }
1176 return obj;
1177};
1178
1179exports.implement = function(proto, mixin) {
1180 exports.mixin(proto, mixin);
1181};
1182
1183});
1184
1185ace.define("ace/lib/keys",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop"], function(acequire, exports, module) {
1186
1187acequire("./fixoldbrowsers");
1188
1189var oop = acequire("./oop");
1190var Keys = (function() {
1191 var ret = {
1192 MODIFIER_KEYS: {
1193 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
1194 },
1195
1196 KEY_MODS: {
1197 "ctrl": 1, "alt": 2, "option" : 2, "shift": 4,
1198 "super": 8, "meta": 8, "command": 8, "cmd": 8
1199 },
1200
1201 FUNCTION_KEYS : {
1202 8 : "Backspace",
1203 9 : "Tab",
1204 13 : "Return",
1205 19 : "Pause",
1206 27 : "Esc",
1207 32 : "Space",
1208 33 : "PageUp",
1209 34 : "PageDown",
1210 35 : "End",
1211 36 : "Home",
1212 37 : "Left",
1213 38 : "Up",
1214 39 : "Right",
1215 40 : "Down",
1216 44 : "Print",
1217 45 : "Insert",
1218 46 : "Delete",
1219 96 : "Numpad0",
1220 97 : "Numpad1",
1221 98 : "Numpad2",
1222 99 : "Numpad3",
1223 100: "Numpad4",
1224 101: "Numpad5",
1225 102: "Numpad6",
1226 103: "Numpad7",
1227 104: "Numpad8",
1228 105: "Numpad9",
1229 '-13': "NumpadEnter",
1230 112: "F1",
1231 113: "F2",
1232 114: "F3",
1233 115: "F4",
1234 116: "F5",
1235 117: "F6",
1236 118: "F7",
1237 119: "F8",
1238 120: "F9",
1239 121: "F10",
1240 122: "F11",
1241 123: "F12",
1242 144: "Numlock",
1243 145: "Scrolllock"
1244 },
1245
1246 PRINTABLE_KEYS: {
1247 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5',
1248 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a',
1249 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h',
1250 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',
1251 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
1252 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
1253 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',
1254 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*'
1255 }
1256 };
1257 var name, i;
1258 for (i in ret.FUNCTION_KEYS) {
1259 name = ret.FUNCTION_KEYS[i].toLowerCase();
1260 ret[name] = parseInt(i, 10);
1261 }
1262 for (i in ret.PRINTABLE_KEYS) {
1263 name = ret.PRINTABLE_KEYS[i].toLowerCase();
1264 ret[name] = parseInt(i, 10);
1265 }
1266 oop.mixin(ret, ret.MODIFIER_KEYS);
1267 oop.mixin(ret, ret.PRINTABLE_KEYS);
1268 oop.mixin(ret, ret.FUNCTION_KEYS);
1269 ret.enter = ret["return"];
1270 ret.escape = ret.esc;
1271 ret.del = ret["delete"];
1272 ret[173] = '-';
1273
1274 (function() {
1275 var mods = ["cmd", "ctrl", "alt", "shift"];
1276 for (var i = Math.pow(2, mods.length); i--;) {
1277 ret.KEY_MODS[i] = mods.filter(function(x) {
1278 return i & ret.KEY_MODS[x];
1279 }).join("-") + "-";
1280 }
1281 })();
1282
1283 ret.KEY_MODS[0] = "";
1284 ret.KEY_MODS[-1] = "input-";
1285
1286 return ret;
1287})();
1288oop.mixin(exports, Keys);
1289
1290exports.keyCodeToString = function(keyCode) {
1291 var keyString = Keys[keyCode];
1292 if (typeof keyString != "string")
1293 keyString = String.fromCharCode(keyCode);
1294 return keyString.toLowerCase();
1295};
1296
1297});
1298
1299ace.define("ace/lib/useragent",["require","exports","module"], function(acequire, exports, module) {
1300exports.OS = {
1301 LINUX: "LINUX",
1302 MAC: "MAC",
1303 WINDOWS: "WINDOWS"
1304};
1305exports.getOS = function() {
1306 if (exports.isMac) {
1307 return exports.OS.MAC;
1308 } else if (exports.isLinux) {
1309 return exports.OS.LINUX;
1310 } else {
1311 return exports.OS.WINDOWS;
1312 }
1313};
1314if (typeof navigator != "object")
1315 return;
1316
1317var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
1318var ua = navigator.userAgent;
1319exports.isWin = (os == "win");
1320exports.isMac = (os == "mac");
1321exports.isLinux = (os == "linux");
1322exports.isIE =
1323 (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
1324 ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1])
1325 : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie
1326
1327exports.isOldIE = exports.isIE && exports.isIE < 9;
1328exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko";
1329exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv:(\d+)/)||[])[1], 10) < 4;
1330exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
1331exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
1332
1333exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
1334
1335exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
1336
1337exports.isIPad = ua.indexOf("iPad") >= 0;
1338
1339exports.isChromeOS = ua.indexOf(" CrOS ") >= 0;
1340
1341exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
1342
1343if (exports.isIOS) exports.isMac = true;
1344
1345});
1346
1347ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(acequire, exports, module) {
1348
1349var keys = acequire("./keys");
1350var useragent = acequire("./useragent");
1351
1352var pressedKeys = null;
1353var ts = 0;
1354
1355exports.addListener = function(elem, type, callback) {
1356 if (elem.addEventListener) {
1357 return elem.addEventListener(type, callback, false);
1358 }
1359 if (elem.attachEvent) {
1360 var wrapper = function() {
1361 callback.call(elem, window.event);
1362 };
1363 callback._wrapper = wrapper;
1364 elem.attachEvent("on" + type, wrapper);
1365 }
1366};
1367
1368exports.removeListener = function(elem, type, callback) {
1369 if (elem.removeEventListener) {
1370 return elem.removeEventListener(type, callback, false);
1371 }
1372 if (elem.detachEvent) {
1373 elem.detachEvent("on" + type, callback._wrapper || callback);
1374 }
1375};
1376exports.stopEvent = function(e) {
1377 exports.stopPropagation(e);
1378 exports.preventDefault(e);
1379 return false;
1380};
1381
1382exports.stopPropagation = function(e) {
1383 if (e.stopPropagation)
1384 e.stopPropagation();
1385 else
1386 e.cancelBubble = true;
1387};
1388
1389exports.preventDefault = function(e) {
1390 if (e.preventDefault)
1391 e.preventDefault();
1392 else
1393 e.returnValue = false;
1394};
1395exports.getButton = function(e) {
1396 if (e.type == "dblclick")
1397 return 0;
1398 if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
1399 return 2;
1400 if (e.preventDefault) {
1401 return e.button;
1402 }
1403 else {
1404 return {1:0, 2:2, 4:1}[e.button];
1405 }
1406};
1407
1408exports.capture = function(el, eventHandler, releaseCaptureHandler) {
1409 function onMouseUp(e) {
1410 eventHandler && eventHandler(e);
1411 releaseCaptureHandler && releaseCaptureHandler(e);
1412
1413 exports.removeListener(document, "mousemove", eventHandler, true);
1414 exports.removeListener(document, "mouseup", onMouseUp, true);
1415 exports.removeListener(document, "dragstart", onMouseUp, true);
1416 }
1417
1418 exports.addListener(document, "mousemove", eventHandler, true);
1419 exports.addListener(document, "mouseup", onMouseUp, true);
1420 exports.addListener(document, "dragstart", onMouseUp, true);
1421
1422 return onMouseUp;
1423};
1424
1425exports.addTouchMoveListener = function (el, callback) {
1426 var startx, starty;
1427 exports.addListener(el, "touchstart", function (e) {
1428 var touches = e.touches;
1429 var touchObj = touches[0];
1430 startx = touchObj.clientX;
1431 starty = touchObj.clientY;
1432 });
1433 exports.addListener(el, "touchmove", function (e) {
1434 var touches = e.touches;
1435 if (touches.length > 1) return;
1436
1437 var touchObj = touches[0];
1438
1439 e.wheelX = startx - touchObj.clientX;
1440 e.wheelY = starty - touchObj.clientY;
1441
1442 startx = touchObj.clientX;
1443 starty = touchObj.clientY;
1444
1445 callback(e);
1446 });
1447};
1448
1449exports.addMouseWheelListener = function(el, callback) {
1450 if ("onmousewheel" in el) {
1451 exports.addListener(el, "mousewheel", function(e) {
1452 var factor = 8;
1453 if (e.wheelDeltaX !== undefined) {
1454 e.wheelX = -e.wheelDeltaX / factor;
1455 e.wheelY = -e.wheelDeltaY / factor;
1456 } else {
1457 e.wheelX = 0;
1458 e.wheelY = -e.wheelDelta / factor;
1459 }
1460 callback(e);
1461 });
1462 } else if ("onwheel" in el) {
1463 exports.addListener(el, "wheel", function(e) {
1464 var factor = 0.35;
1465 switch (e.deltaMode) {
1466 case e.DOM_DELTA_PIXEL:
1467 e.wheelX = e.deltaX * factor || 0;
1468 e.wheelY = e.deltaY * factor || 0;
1469 break;
1470 case e.DOM_DELTA_LINE:
1471 case e.DOM_DELTA_PAGE:
1472 e.wheelX = (e.deltaX || 0) * 5;
1473 e.wheelY = (e.deltaY || 0) * 5;
1474 break;
1475 }
1476
1477 callback(e);
1478 });
1479 } else {
1480 exports.addListener(el, "DOMMouseScroll", function(e) {
1481 if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
1482 e.wheelX = (e.detail || 0) * 5;
1483 e.wheelY = 0;
1484 } else {
1485 e.wheelX = 0;
1486 e.wheelY = (e.detail || 0) * 5;
1487 }
1488 callback(e);
1489 });
1490 }
1491};
1492
1493exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName) {
1494 var clicks = 0;
1495 var startX, startY, timer;
1496 var eventNames = {
1497 2: "dblclick",
1498 3: "tripleclick",
1499 4: "quadclick"
1500 };
1501
1502 function onMousedown(e) {
1503 if (exports.getButton(e) !== 0) {
1504 clicks = 0;
1505 } else if (e.detail > 1) {
1506 clicks++;
1507 if (clicks > 4)
1508 clicks = 1;
1509 } else {
1510 clicks = 1;
1511 }
1512 if (useragent.isIE) {
1513 var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
1514 if (!timer || isNewClick)
1515 clicks = 1;
1516 if (timer)
1517 clearTimeout(timer);
1518 timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
1519
1520 if (clicks == 1) {
1521 startX = e.clientX;
1522 startY = e.clientY;
1523 }
1524 }
1525
1526 e._clicks = clicks;
1527
1528 eventHandler[callbackName]("mousedown", e);
1529
1530 if (clicks > 4)
1531 clicks = 0;
1532 else if (clicks > 1)
1533 return eventHandler[callbackName](eventNames[clicks], e);
1534 }
1535 function onDblclick(e) {
1536 clicks = 2;
1537 if (timer)
1538 clearTimeout(timer);
1539 timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
1540 eventHandler[callbackName]("mousedown", e);
1541 eventHandler[callbackName](eventNames[clicks], e);
1542 }
1543 if (!Array.isArray(elements))
1544 elements = [elements];
1545 elements.forEach(function(el) {
1546 exports.addListener(el, "mousedown", onMousedown);
1547 if (useragent.isOldIE)
1548 exports.addListener(el, "dblclick", onDblclick);
1549 });
1550};
1551
1552var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window)
1553 ? function(e) {
1554 return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
1555 }
1556 : function(e) {
1557 return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
1558 };
1559
1560exports.getModifierString = function(e) {
1561 return keys.KEY_MODS[getModifierHash(e)];
1562};
1563
1564function normalizeCommandKeys(callback, e, keyCode) {
1565 var hashId = getModifierHash(e);
1566
1567 if (!useragent.isMac && pressedKeys) {
1568 if (e.getModifierState && (e.getModifierState("OS") || e.getModifierState("Win")))
1569 hashId |= 8;
1570 if (pressedKeys.altGr) {
1571 if ((3 & hashId) != 3)
1572 pressedKeys.altGr = 0;
1573 else
1574 return;
1575 }
1576 if (keyCode === 18 || keyCode === 17) {
1577 var location = "location" in e ? e.location : e.keyLocation;
1578 if (keyCode === 17 && location === 1) {
1579 if (pressedKeys[keyCode] == 1)
1580 ts = e.timeStamp;
1581 } else if (keyCode === 18 && hashId === 3 && location === 2) {
1582 var dt = e.timeStamp - ts;
1583 if (dt < 50)
1584 pressedKeys.altGr = true;
1585 }
1586 }
1587 }
1588
1589 if (keyCode in keys.MODIFIER_KEYS) {
1590 keyCode = -1;
1591 }
1592 if (hashId & 8 && (keyCode >= 91 && keyCode <= 93)) {
1593 keyCode = -1;
1594 }
1595
1596 if (!hashId && keyCode === 13) {
1597 var location = "location" in e ? e.location : e.keyLocation;
1598 if (location === 3) {
1599 callback(e, hashId, -keyCode);
1600 if (e.defaultPrevented)
1601 return;
1602 }
1603 }
1604
1605 if (useragent.isChromeOS && hashId & 8) {
1606 callback(e, hashId, keyCode);
1607 if (e.defaultPrevented)
1608 return;
1609 else
1610 hashId &= ~8;
1611 }
1612 if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
1613 return false;
1614 }
1615
1616 return callback(e, hashId, keyCode);
1617}
1618
1619
1620exports.addCommandKeyListener = function(el, callback) {
1621 var addListener = exports.addListener;
1622 if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
1623 var lastKeyDownKeyCode = null;
1624 addListener(el, "keydown", function(e) {
1625 lastKeyDownKeyCode = e.keyCode;
1626 });
1627 addListener(el, "keypress", function(e) {
1628 return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);
1629 });
1630 } else {
1631 var lastDefaultPrevented = null;
1632
1633 addListener(el, "keydown", function(e) {
1634 pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1;
1635 var result = normalizeCommandKeys(callback, e, e.keyCode);
1636 lastDefaultPrevented = e.defaultPrevented;
1637 return result;
1638 });
1639
1640 addListener(el, "keypress", function(e) {
1641 if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {
1642 exports.stopEvent(e);
1643 lastDefaultPrevented = null;
1644 }
1645 });
1646
1647 addListener(el, "keyup", function(e) {
1648 pressedKeys[e.keyCode] = null;
1649 });
1650
1651 if (!pressedKeys) {
1652 resetPressedKeys();
1653 addListener(window, "focus", resetPressedKeys);
1654 }
1655 }
1656};
1657function resetPressedKeys() {
1658 pressedKeys = Object.create(null);
1659}
1660
1661if (typeof window == "object" && window.postMessage && !useragent.isOldIE) {
1662 var postMessageId = 1;
1663 exports.nextTick = function(callback, win) {
1664 win = win || window;
1665 var messageName = "zero-timeout-message-" + postMessageId;
1666 exports.addListener(win, "message", function listener(e) {
1667 if (e.data == messageName) {
1668 exports.stopPropagation(e);
1669 exports.removeListener(win, "message", listener);
1670 callback();
1671 }
1672 });
1673 win.postMessage(messageName, "*");
1674 };
1675}
1676
1677
1678exports.nextFrame = typeof window == "object" && (window.requestAnimationFrame
1679 || window.mozRequestAnimationFrame
1680 || window.webkitRequestAnimationFrame
1681 || window.msRequestAnimationFrame
1682 || window.oRequestAnimationFrame);
1683
1684if (exports.nextFrame)
1685 exports.nextFrame = exports.nextFrame.bind(window);
1686else
1687 exports.nextFrame = function(callback) {
1688 setTimeout(callback, 17);
1689 };
1690});
1691
1692ace.define("ace/lib/lang",["require","exports","module"], function(acequire, exports, module) {
1693
1694exports.last = function(a) {
1695 return a[a.length - 1];
1696};
1697
1698exports.stringReverse = function(string) {
1699 return string.split("").reverse().join("");
1700};
1701
1702exports.stringRepeat = function (string, count) {
1703 var result = '';
1704 while (count > 0) {
1705 if (count & 1)
1706 result += string;
1707
1708 if (count >>= 1)
1709 string += string;
1710 }
1711 return result;
1712};
1713
1714var trimBeginRegexp = /^\s\s*/;
1715var trimEndRegexp = /\s\s*$/;
1716
1717exports.stringTrimLeft = function (string) {
1718 return string.replace(trimBeginRegexp, '');
1719};
1720
1721exports.stringTrimRight = function (string) {
1722 return string.replace(trimEndRegexp, '');
1723};
1724
1725exports.copyObject = function(obj) {
1726 var copy = {};
1727 for (var key in obj) {
1728 copy[key] = obj[key];
1729 }
1730 return copy;
1731};
1732
1733exports.copyArray = function(array){
1734 var copy = [];
1735 for (var i=0, l=array.length; i<l; i++) {
1736 if (array[i] && typeof array[i] == "object")
1737 copy[i] = this.copyObject(array[i]);
1738 else
1739 copy[i] = array[i];
1740 }
1741 return copy;
1742};
1743
1744exports.deepCopy = function deepCopy(obj) {
1745 if (typeof obj !== "object" || !obj)
1746 return obj;
1747 var copy;
1748 if (Array.isArray(obj)) {
1749 copy = [];
1750 for (var key = 0; key < obj.length; key++) {
1751 copy[key] = deepCopy(obj[key]);
1752 }
1753 return copy;
1754 }
1755 if (Object.prototype.toString.call(obj) !== "[object Object]")
1756 return obj;
1757
1758 copy = {};
1759 for (var key in obj)
1760 copy[key] = deepCopy(obj[key]);
1761 return copy;
1762};
1763
1764exports.arrayToMap = function(arr) {
1765 var map = {};
1766 for (var i=0; i<arr.length; i++) {
1767 map[arr[i]] = 1;
1768 }
1769 return map;
1770
1771};
1772
1773exports.createMap = function(props) {
1774 var map = Object.create(null);
1775 for (var i in props) {
1776 map[i] = props[i];
1777 }
1778 return map;
1779};
1780exports.arrayRemove = function(array, value) {
1781 for (var i = 0; i <= array.length; i++) {
1782 if (value === array[i]) {
1783 array.splice(i, 1);
1784 }
1785 }
1786};
1787
1788exports.escapeRegExp = function(str) {
1789 return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1790};
1791
1792exports.escapeHTML = function(str) {
1793 return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
1794};
1795
1796exports.getMatchOffsets = function(string, regExp) {
1797 var matches = [];
1798
1799 string.replace(regExp, function(str) {
1800 matches.push({
1801 offset: arguments[arguments.length-2],
1802 length: str.length
1803 });
1804 });
1805
1806 return matches;
1807};
1808exports.deferredCall = function(fcn) {
1809 var timer = null;
1810 var callback = function() {
1811 timer = null;
1812 fcn();
1813 };
1814
1815 var deferred = function(timeout) {
1816 deferred.cancel();
1817 timer = setTimeout(callback, timeout || 0);
1818 return deferred;
1819 };
1820
1821 deferred.schedule = deferred;
1822
1823 deferred.call = function() {
1824 this.cancel();
1825 fcn();
1826 return deferred;
1827 };
1828
1829 deferred.cancel = function() {
1830 clearTimeout(timer);
1831 timer = null;
1832 return deferred;
1833 };
1834
1835 deferred.isPending = function() {
1836 return timer;
1837 };
1838
1839 return deferred;
1840};
1841
1842
1843exports.delayedCall = function(fcn, defaultTimeout) {
1844 var timer = null;
1845 var callback = function() {
1846 timer = null;
1847 fcn();
1848 };
1849
1850 var _self = function(timeout) {
1851 if (timer == null)
1852 timer = setTimeout(callback, timeout || defaultTimeout);
1853 };
1854
1855 _self.delay = function(timeout) {
1856 timer && clearTimeout(timer);
1857 timer = setTimeout(callback, timeout || defaultTimeout);
1858 };
1859 _self.schedule = _self;
1860
1861 _self.call = function() {
1862 this.cancel();
1863 fcn();
1864 };
1865
1866 _self.cancel = function() {
1867 timer && clearTimeout(timer);
1868 timer = null;
1869 };
1870
1871 _self.isPending = function() {
1872 return timer;
1873 };
1874
1875 return _self;
1876};
1877});
1878
1879ace.define("ace/keyboard/textinput_ios",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/lib/keys"], function(acequire, exports, module) {
1880
1881var event = acequire("../lib/event");
1882var useragent = acequire("../lib/useragent");
1883var dom = acequire("../lib/dom");
1884var lang = acequire("../lib/lang");
1885var KEYS = acequire("../lib/keys");
1886var MODS = KEYS.KEY_MODS;
1887var BROKEN_SETDATA = useragent.isChrome < 18;
1888var USE_IE_MIME_TYPE = useragent.isIE;
1889
1890var TextInput = function(parentNode, host) {
1891 var text = dom.createElement("textarea");
1892 text.className = useragent.isIOS ? "ace_text-input ace_text-input-ios" : "ace_text-input";
1893
1894 if (useragent.isTouchPad)
1895 text.setAttribute("x-palm-disable-auto-cap", true);
1896
1897 text.setAttribute("wrap", "off");
1898 text.setAttribute("autocorrect", "off");
1899 text.setAttribute("autocapitalize", "off");
1900 text.setAttribute("spellcheck", false);
1901
1902 text.style.opacity = "0";
1903 parentNode.insertBefore(text, parentNode.firstChild);
1904
1905 var PLACEHOLDER = "\n aaaa a\n";
1906
1907 var copied = false;
1908 var cut = false;
1909 var pasted = false;
1910 var inComposition = false;
1911 var tempStyle = '';
1912 var isSelectionEmpty = true;
1913 try { var isFocused = document.activeElement === text; } catch(e) {}
1914
1915 event.addListener(text, "blur", function(e) {
1916 host.onBlur(e);
1917 isFocused = false;
1918 });
1919 event.addListener(text, "focus", function(e) {
1920 isFocused = true;
1921 host.onFocus(e);
1922 resetSelection();
1923 });
1924 this.focus = function() {
1925 if (tempStyle) return text.focus();
1926 text.style.position = "fixed";
1927 text.focus();
1928 };
1929 this.blur = function() {
1930 text.blur();
1931 };
1932 this.isFocused = function() {
1933 return isFocused;
1934 };
1935 var syncSelection = lang.delayedCall(function() {
1936 isFocused && resetSelection(isSelectionEmpty);
1937 });
1938 var syncValue = lang.delayedCall(function() {
1939 if (!inComposition) {
1940 text.value = PLACEHOLDER;
1941 isFocused && resetSelection();
1942 }
1943 });
1944
1945 function resetSelection(isEmpty) {
1946 if (inComposition)
1947 return;
1948 inComposition = true;
1949
1950 if (inputHandler) {
1951 selectionStart = 0;
1952 selectionEnd = isEmpty ? 0 : text.value.length - 1;
1953 } else {
1954 var selectionStart = 4;
1955 var selectionEnd = 5;
1956 }
1957 try {
1958 text.setSelectionRange(selectionStart, selectionEnd);
1959 } catch(e) {}
1960
1961 inComposition = false;
1962 }
1963
1964 function resetValue() {
1965 if (inComposition)
1966 return;
1967 text.value = PLACEHOLDER;
1968 if (useragent.isWebKit)
1969 syncValue.schedule();
1970 }
1971
1972 useragent.isWebKit || host.addEventListener('changeSelection', function() {
1973 if (host.selection.isEmpty() != isSelectionEmpty) {
1974 isSelectionEmpty = !isSelectionEmpty;
1975 syncSelection.schedule();
1976 }
1977 });
1978
1979 resetValue();
1980 if (isFocused)
1981 host.onFocus();
1982
1983
1984 var isAllSelected = function(text) {
1985 return text.selectionStart === 0 && text.selectionEnd === text.value.length;
1986 };
1987
1988 var onSelect = function(e) {
1989 if (isAllSelected(text)) {
1990 host.selectAll();
1991 resetSelection();
1992 } else if (inputHandler) {
1993 resetSelection(host.selection.isEmpty());
1994 }
1995 };
1996
1997 var inputHandler = null;
1998 this.setInputHandler = function(cb) {inputHandler = cb;};
1999 this.getInputHandler = function() {return inputHandler;};
2000 var afterContextMenu = false;
2001
2002 var sendText = function(data) {
2003 if (text.selectionStart === 4 && text.selectionEnd === 5) {
2004 return;
2005 }
2006 if (inputHandler) {
2007 data = inputHandler(data);
2008 inputHandler = null;
2009 }
2010 if (pasted) {
2011 resetSelection();
2012 if (data)
2013 host.onPaste(data);
2014 pasted = false;
2015 } else if (data == PLACEHOLDER.substr(0) && text.selectionStart === 4) {
2016 if (afterContextMenu)
2017 host.execCommand("del", {source: "ace"});
2018 else // some versions of android do not fire keydown when pressing backspace
2019 host.execCommand("backspace", {source: "ace"});
2020 } else if (!copied) {
2021 if (data.substring(0, 9) == PLACEHOLDER && data.length > PLACEHOLDER.length)
2022 data = data.substr(9);
2023 else if (data.substr(0, 4) == PLACEHOLDER.substr(0, 4))
2024 data = data.substr(4, data.length - PLACEHOLDER.length + 1);
2025 else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2026 data = data.slice(0, -1);
2027 if (data == PLACEHOLDER.charAt(0)) ; else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2028 data = data.slice(0, -1);
2029
2030 if (data)
2031 host.onTextInput(data);
2032 }
2033 if (copied) {
2034 copied = false;
2035 }
2036 if (afterContextMenu)
2037 afterContextMenu = false;
2038 };
2039 var onInput = function(e) {
2040 if (inComposition)
2041 return;
2042 var data = text.value;
2043 sendText(data);
2044 resetValue();
2045 };
2046
2047 var handleClipboardData = function(e, data, forceIEMime) {
2048 var clipboardData = e.clipboardData || window.clipboardData;
2049 if (!clipboardData || BROKEN_SETDATA)
2050 return;
2051 var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain";
2052 try {
2053 if (data) {
2054 return clipboardData.setData(mime, data) !== false;
2055 } else {
2056 return clipboardData.getData(mime);
2057 }
2058 } catch(e) {
2059 if (!forceIEMime)
2060 return handleClipboardData(e, data, true);
2061 }
2062 };
2063
2064 var doCopy = function(e, isCut) {
2065 var data = host.getCopyText();
2066 if (!data)
2067 return event.preventDefault(e);
2068
2069 if (handleClipboardData(e, data)) {
2070 if (useragent.isIOS) {
2071 cut = isCut;
2072 text.value = "\n aa" + data + "a a\n";
2073 text.setSelectionRange(4, 4 + data.length);
2074 copied = {
2075 value: data
2076 };
2077 }
2078 isCut ? host.onCut() : host.onCopy();
2079 if (!useragent.isIOS) event.preventDefault(e);
2080 } else {
2081 copied = true;
2082 text.value = data;
2083 text.select();
2084 setTimeout(function(){
2085 copied = false;
2086 resetValue();
2087 resetSelection();
2088 isCut ? host.onCut() : host.onCopy();
2089 });
2090 }
2091 };
2092
2093 var onCut = function(e) {
2094 doCopy(e, true);
2095 };
2096
2097 var onCopy = function(e) {
2098 doCopy(e, false);
2099 };
2100
2101 var onPaste = function(e) {
2102 var data = handleClipboardData(e);
2103 if (typeof data == "string") {
2104 if (data)
2105 host.onPaste(data, e);
2106 if (useragent.isIE)
2107 setTimeout(resetSelection);
2108 event.preventDefault(e);
2109 }
2110 else {
2111 text.value = "";
2112 pasted = true;
2113 }
2114 };
2115
2116 event.addCommandKeyListener(text, host.onCommandKey.bind(host));
2117
2118 event.addListener(text, "select", onSelect);
2119
2120 event.addListener(text, "input", onInput);
2121
2122 event.addListener(text, "cut", onCut);
2123 event.addListener(text, "copy", onCopy);
2124 event.addListener(text, "paste", onPaste);
2125 var onCompositionStart = function(e) {
2126 if (inComposition || !host.onCompositionStart || host.$readOnly)
2127 return;
2128 inComposition = {};
2129 inComposition.canUndo = host.session.$undoManager;
2130 host.onCompositionStart();
2131 setTimeout(onCompositionUpdate, 0);
2132 host.on("mousedown", onCompositionEnd);
2133 if (inComposition.canUndo && !host.selection.isEmpty()) {
2134 host.insert("");
2135 host.session.markUndoGroup();
2136 host.selection.clearSelection();
2137 }
2138 host.session.markUndoGroup();
2139 };
2140
2141 var onCompositionUpdate = function() {
2142 if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
2143 return;
2144 var val = text.value.replace(/\x01/g, "");
2145 if (inComposition.lastValue === val) return;
2146
2147 host.onCompositionUpdate(val);
2148 if (inComposition.lastValue)
2149 host.undo();
2150 if (inComposition.canUndo)
2151 inComposition.lastValue = val;
2152 if (inComposition.lastValue) {
2153 var r = host.selection.getRange();
2154 host.insert(inComposition.lastValue);
2155 host.session.markUndoGroup();
2156 inComposition.range = host.selection.getRange();
2157 host.selection.setRange(r);
2158 host.selection.clearSelection();
2159 }
2160 };
2161
2162 var onCompositionEnd = function(e) {
2163 if (!host.onCompositionEnd || host.$readOnly) return;
2164 var c = inComposition;
2165 inComposition = false;
2166 var timer = setTimeout(function() {
2167 timer = null;
2168 var str = text.value.replace(/\x01/g, "");
2169 if (inComposition)
2170 return;
2171 else if (str == c.lastValue)
2172 resetValue();
2173 else if (!c.lastValue && str) {
2174 resetValue();
2175 sendText(str);
2176 }
2177 });
2178 inputHandler = function compositionInputHandler(str) {
2179 if (timer)
2180 clearTimeout(timer);
2181 str = str.replace(/\x01/g, "");
2182 if (str == c.lastValue)
2183 return "";
2184 if (c.lastValue && timer)
2185 host.undo();
2186 return str;
2187 };
2188 host.onCompositionEnd();
2189 host.removeListener("mousedown", onCompositionEnd);
2190 if (e.type == "compositionend" && c.range) {
2191 host.selection.setRange(c.range);
2192 }
2193 var needsOnInput =
2194 (!!useragent.isChrome && useragent.isChrome >= 53) ||
2195 (!!useragent.isWebKit && useragent.isWebKit >= 603);
2196
2197 if (needsOnInput) {
2198 onInput();
2199 }
2200 };
2201
2202
2203
2204 var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
2205
2206 event.addListener(text, "compositionstart", onCompositionStart);
2207 if (useragent.isGecko) {
2208 event.addListener(text, "text", function(){syncComposition.schedule();});
2209 } else {
2210 event.addListener(text, "keyup", function(){syncComposition.schedule();});
2211 event.addListener(text, "keydown", function(){syncComposition.schedule();});
2212 }
2213 event.addListener(text, "compositionend", onCompositionEnd);
2214
2215 this.getElement = function() {
2216 return text;
2217 };
2218
2219 this.setReadOnly = function(readOnly) {
2220 text.readOnly = readOnly;
2221 };
2222
2223 this.onContextMenu = function(e) {
2224 afterContextMenu = true;
2225 resetSelection(host.selection.isEmpty());
2226 host._emit("nativecontextmenu", {target: host, domEvent: e});
2227 this.moveToMouse(e, true);
2228 };
2229
2230 this.moveToMouse = function(e, bringToFront) {
2231 if (!tempStyle)
2232 tempStyle = text.style.cssText;
2233 text.style.cssText = (bringToFront ? "z-index:100000;" : "")
2234 + "height:" + text.style.height + ";"
2235 + (useragent.isIE ? "opacity:0.1;" : "");
2236
2237 var rect = host.container.getBoundingClientRect();
2238 var style = dom.computedStyle(host.container);
2239 var top = rect.top + (parseInt(style.borderTopWidth) || 0);
2240 var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
2241 var maxTop = rect.bottom - top - text.clientHeight -2;
2242 var move = function(e) {
2243 text.style.left = e.clientX - left - 2 + "px";
2244 text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
2245 };
2246 move(e);
2247
2248 if (e.type != "mousedown")
2249 return;
2250
2251 if (host.renderer.$keepTextAreaAtCursor)
2252 host.renderer.$keepTextAreaAtCursor = null;
2253
2254 clearTimeout(closeTimeout);
2255 if (useragent.isWin)
2256 event.capture(host.container, move, onContextMenuClose);
2257 };
2258
2259 this.onContextMenuClose = onContextMenuClose;
2260 var closeTimeout;
2261 function onContextMenuClose() {
2262 clearTimeout(closeTimeout);
2263 closeTimeout = setTimeout(function () {
2264 if (tempStyle) {
2265 text.style.cssText = tempStyle;
2266 tempStyle = '';
2267 }
2268 if (host.renderer.$keepTextAreaAtCursor == null) {
2269 host.renderer.$keepTextAreaAtCursor = true;
2270 host.renderer.$moveTextAreaToCursor();
2271 }
2272 }, 0);
2273 }
2274
2275 var onContextMenu = function(e) {
2276 host.textInput.onContextMenu(e);
2277 onContextMenuClose();
2278 };
2279 event.addListener(text, "mouseup", onContextMenu);
2280 event.addListener(text, "mousedown", function(e) {
2281 e.preventDefault();
2282 onContextMenuClose();
2283 });
2284 event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
2285 event.addListener(text, "contextmenu", onContextMenu);
2286
2287 if (useragent.isIOS) {
2288 var typingResetTimeout = null;
2289 var typing = false;
2290
2291 parentNode.addEventListener("keydown", function (e) {
2292 if (typingResetTimeout) clearTimeout(typingResetTimeout);
2293 typing = true;
2294 });
2295
2296 parentNode.addEventListener("keyup", function (e) {
2297 typingResetTimeout = setTimeout(function () {
2298 typing = false;
2299 }, 100);
2300 });
2301 var detectArrowKeys = function(e) {
2302 if (document.activeElement !== text) return;
2303 if (typing) return;
2304
2305 if (cut) {
2306 return setTimeout(function () {
2307 cut = false;
2308 }, 100);
2309 }
2310 var selectionStart = text.selectionStart;
2311 var selectionEnd = text.selectionEnd;
2312 text.setSelectionRange(4, 5);
2313 if (selectionStart == selectionEnd) {
2314 switch (selectionStart) {
2315 case 0: host.onCommandKey(null, 0, KEYS.up); break;
2316 case 1: host.onCommandKey(null, 0, KEYS.home); break;
2317 case 2: host.onCommandKey(null, MODS.option, KEYS.left); break;
2318 case 4: host.onCommandKey(null, 0, KEYS.left); break;
2319 case 5: host.onCommandKey(null, 0, KEYS.right); break;
2320 case 7: host.onCommandKey(null, MODS.option, KEYS.right); break;
2321 case 8: host.onCommandKey(null, 0, KEYS.end); break;
2322 case 9: host.onCommandKey(null, 0, KEYS.down); break;
2323 }
2324 } else {
2325 switch (selectionEnd) {
2326 case 6: host.onCommandKey(null, MODS.shift, KEYS.right); break;
2327 case 7: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.right); break;
2328 case 8: host.onCommandKey(null, MODS.shift, KEYS.end); break;
2329 case 9: host.onCommandKey(null, MODS.shift, KEYS.down); break;
2330 }
2331 switch (selectionStart) {
2332 case 0: host.onCommandKey(null, MODS.shift, KEYS.up); break;
2333 case 1: host.onCommandKey(null, MODS.shift, KEYS.home); break;
2334 case 2: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.left); break;
2335 case 3: host.onCommandKey(null, MODS.shift, KEYS.left); break;
2336 }
2337 }
2338 };
2339 document.addEventListener("selectionchange", detectArrowKeys);
2340 host.on("destroy", function() {
2341 document.removeEventListener("selectionchange", detectArrowKeys);
2342 });
2343 }
2344};
2345
2346exports.TextInput = TextInput;
2347});
2348
2349ace.define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/keyboard/textinput_ios"], function(acequire, exports, module) {
2350
2351var event = acequire("../lib/event");
2352var useragent = acequire("../lib/useragent");
2353var dom = acequire("../lib/dom");
2354var lang = acequire("../lib/lang");
2355var BROKEN_SETDATA = useragent.isChrome < 18;
2356var USE_IE_MIME_TYPE = useragent.isIE;
2357
2358var TextInputIOS = acequire("./textinput_ios").TextInput;
2359var TextInput = function(parentNode, host) {
2360 if (useragent.isIOS)
2361 return TextInputIOS.call(this, parentNode, host);
2362
2363 var text = dom.createElement("textarea");
2364 text.className = "ace_text-input";
2365
2366 text.setAttribute("wrap", "off");
2367 text.setAttribute("autocorrect", "off");
2368 text.setAttribute("autocapitalize", "off");
2369 text.setAttribute("spellcheck", false);
2370
2371 text.style.opacity = "0";
2372 parentNode.insertBefore(text, parentNode.firstChild);
2373
2374 var PLACEHOLDER = "\u2028\u2028";
2375
2376 var copied = false;
2377 var pasted = false;
2378 var inComposition = false;
2379 var tempStyle = '';
2380 var isSelectionEmpty = true;
2381 try { var isFocused = document.activeElement === text; } catch(e) {}
2382
2383 event.addListener(text, "blur", function(e) {
2384 host.onBlur(e);
2385 isFocused = false;
2386 });
2387 event.addListener(text, "focus", function(e) {
2388 isFocused = true;
2389 host.onFocus(e);
2390 resetSelection();
2391 });
2392 this.focus = function() {
2393 if (tempStyle) return text.focus();
2394 var top = text.style.top;
2395 text.style.position = "fixed";
2396 text.style.top = "0px";
2397 text.focus();
2398 setTimeout(function() {
2399 text.style.position = "";
2400 if (text.style.top == "0px")
2401 text.style.top = top;
2402 }, 0);
2403 };
2404 this.blur = function() {
2405 text.blur();
2406 };
2407 this.isFocused = function() {
2408 return isFocused;
2409 };
2410 var syncSelection = lang.delayedCall(function() {
2411 isFocused && resetSelection(isSelectionEmpty);
2412 });
2413 var syncValue = lang.delayedCall(function() {
2414 if (!inComposition) {
2415 text.value = PLACEHOLDER;
2416 isFocused && resetSelection();
2417 }
2418 });
2419
2420 function resetSelection(isEmpty) {
2421 if (inComposition)
2422 return;
2423 inComposition = true;
2424
2425 if (inputHandler) {
2426 var selectionStart = 0;
2427 var selectionEnd = isEmpty ? 0 : text.value.length - 1;
2428 } else {
2429 var selectionStart = isEmpty ? 2 : 1;
2430 var selectionEnd = 2;
2431 }
2432 try {
2433 text.setSelectionRange(selectionStart, selectionEnd);
2434 } catch(e){}
2435
2436 inComposition = false;
2437 }
2438
2439 function resetValue() {
2440 if (inComposition)
2441 return;
2442 text.value = PLACEHOLDER;
2443 if (useragent.isWebKit)
2444 syncValue.schedule();
2445 }
2446
2447 useragent.isWebKit || host.addEventListener('changeSelection', function() {
2448 if (host.selection.isEmpty() != isSelectionEmpty) {
2449 isSelectionEmpty = !isSelectionEmpty;
2450 syncSelection.schedule();
2451 }
2452 });
2453
2454 resetValue();
2455 if (isFocused)
2456 host.onFocus();
2457
2458
2459 var isAllSelected = function(text) {
2460 return text.selectionStart === 0 && text.selectionEnd === text.value.length;
2461 };
2462
2463 var onSelect = function(e) {
2464 if (copied) {
2465 copied = false;
2466 } else if (isAllSelected(text)) {
2467 host.selectAll();
2468 resetSelection();
2469 } else if (inputHandler) {
2470 resetSelection(host.selection.isEmpty());
2471 }
2472 };
2473
2474 var inputHandler = null;
2475 this.setInputHandler = function(cb) {inputHandler = cb;};
2476 this.getInputHandler = function() {return inputHandler;};
2477 var afterContextMenu = false;
2478
2479 var sendText = function(data) {
2480 if (inputHandler) {
2481 data = inputHandler(data);
2482 inputHandler = null;
2483 }
2484 if (pasted) {
2485 resetSelection();
2486 if (data)
2487 host.onPaste(data);
2488 pasted = false;
2489 } else if (data == PLACEHOLDER.charAt(0)) {
2490 if (afterContextMenu)
2491 host.execCommand("del", {source: "ace"});
2492 else // some versions of android do not fire keydown when pressing backspace
2493 host.execCommand("backspace", {source: "ace"});
2494 } else {
2495 if (data.substring(0, 2) == PLACEHOLDER)
2496 data = data.substr(2);
2497 else if (data.charAt(0) == PLACEHOLDER.charAt(0))
2498 data = data.substr(1);
2499 else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2500 data = data.slice(0, -1);
2501 if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2502 data = data.slice(0, -1);
2503
2504 if (data)
2505 host.onTextInput(data);
2506 }
2507 if (afterContextMenu)
2508 afterContextMenu = false;
2509 };
2510 var onInput = function(e) {
2511 if (inComposition)
2512 return;
2513 var data = text.value;
2514 sendText(data);
2515 resetValue();
2516 };
2517
2518 var handleClipboardData = function(e, data, forceIEMime) {
2519 var clipboardData = e.clipboardData || window.clipboardData;
2520 if (!clipboardData || BROKEN_SETDATA)
2521 return;
2522 var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain";
2523 try {
2524 if (data) {
2525 return clipboardData.setData(mime, data) !== false;
2526 } else {
2527 return clipboardData.getData(mime);
2528 }
2529 } catch(e) {
2530 if (!forceIEMime)
2531 return handleClipboardData(e, data, true);
2532 }
2533 };
2534
2535 var doCopy = function(e, isCut) {
2536 var data = host.getCopyText();
2537 if (!data)
2538 return event.preventDefault(e);
2539
2540 if (handleClipboardData(e, data)) {
2541 isCut ? host.onCut() : host.onCopy();
2542 event.preventDefault(e);
2543 } else {
2544 copied = true;
2545 text.value = data;
2546 text.select();
2547 setTimeout(function(){
2548 copied = false;
2549 resetValue();
2550 resetSelection();
2551 isCut ? host.onCut() : host.onCopy();
2552 });
2553 }
2554 };
2555
2556 var onCut = function(e) {
2557 doCopy(e, true);
2558 };
2559
2560 var onCopy = function(e) {
2561 doCopy(e, false);
2562 };
2563
2564 var onPaste = function(e) {
2565 var data = handleClipboardData(e);
2566 if (typeof data == "string") {
2567 if (data)
2568 host.onPaste(data, e);
2569 if (useragent.isIE)
2570 setTimeout(resetSelection);
2571 event.preventDefault(e);
2572 }
2573 else {
2574 text.value = "";
2575 pasted = true;
2576 }
2577 };
2578
2579 event.addCommandKeyListener(text, host.onCommandKey.bind(host));
2580
2581 event.addListener(text, "select", onSelect);
2582
2583 event.addListener(text, "input", onInput);
2584
2585 event.addListener(text, "cut", onCut);
2586 event.addListener(text, "copy", onCopy);
2587 event.addListener(text, "paste", onPaste);
2588 if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) {
2589 event.addListener(parentNode, "keydown", function(e) {
2590 if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
2591 return;
2592
2593 switch (e.keyCode) {
2594 case 67:
2595 onCopy(e);
2596 break;
2597 case 86:
2598 onPaste(e);
2599 break;
2600 case 88:
2601 onCut(e);
2602 break;
2603 }
2604 });
2605 }
2606 var onCompositionStart = function(e) {
2607 if (inComposition || !host.onCompositionStart || host.$readOnly)
2608 return;
2609 inComposition = {};
2610 inComposition.canUndo = host.session.$undoManager;
2611 host.onCompositionStart();
2612 setTimeout(onCompositionUpdate, 0);
2613 host.on("mousedown", onCompositionEnd);
2614 if (inComposition.canUndo && !host.selection.isEmpty()) {
2615 host.insert("");
2616 host.session.markUndoGroup();
2617 host.selection.clearSelection();
2618 }
2619 host.session.markUndoGroup();
2620 };
2621
2622 var onCompositionUpdate = function() {
2623 if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
2624 return;
2625 var val = text.value.replace(/\u2028/g, "");
2626 if (inComposition.lastValue === val) return;
2627
2628 host.onCompositionUpdate(val);
2629 if (inComposition.lastValue)
2630 host.undo();
2631 if (inComposition.canUndo)
2632 inComposition.lastValue = val;
2633 if (inComposition.lastValue) {
2634 var r = host.selection.getRange();
2635 host.insert(inComposition.lastValue);
2636 host.session.markUndoGroup();
2637 inComposition.range = host.selection.getRange();
2638 host.selection.setRange(r);
2639 host.selection.clearSelection();
2640 }
2641 };
2642
2643 var onCompositionEnd = function(e) {
2644 if (!host.onCompositionEnd || host.$readOnly) return;
2645 var c = inComposition;
2646 inComposition = false;
2647 var timer = setTimeout(function() {
2648 timer = null;
2649 var str = text.value.replace(/\u2028/g, "");
2650 if (inComposition)
2651 return;
2652 else if (str == c.lastValue)
2653 resetValue();
2654 else if (!c.lastValue && str) {
2655 resetValue();
2656 sendText(str);
2657 }
2658 });
2659 inputHandler = function compositionInputHandler(str) {
2660 if (timer)
2661 clearTimeout(timer);
2662 str = str.replace(/\u2028/g, "");
2663 if (str == c.lastValue)
2664 return "";
2665 if (c.lastValue && timer)
2666 host.undo();
2667 return str;
2668 };
2669 host.onCompositionEnd();
2670 host.removeListener("mousedown", onCompositionEnd);
2671 if (e.type == "compositionend" && c.range) {
2672 host.selection.setRange(c.range);
2673 }
2674 var needsOnInput =
2675 (!!useragent.isChrome && useragent.isChrome >= 53) ||
2676 (!!useragent.isWebKit && useragent.isWebKit >= 603);
2677
2678 if (needsOnInput) {
2679 onInput();
2680 }
2681 };
2682
2683
2684
2685 var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
2686
2687 event.addListener(text, "compositionstart", onCompositionStart);
2688 if (useragent.isGecko) {
2689 event.addListener(text, "text", function(){syncComposition.schedule();});
2690 } else {
2691 event.addListener(text, "keyup", function(){syncComposition.schedule();});
2692 event.addListener(text, "keydown", function(){syncComposition.schedule();});
2693 }
2694 event.addListener(text, "compositionend", onCompositionEnd);
2695
2696 this.getElement = function() {
2697 return text;
2698 };
2699
2700 this.setReadOnly = function(readOnly) {
2701 text.readOnly = readOnly;
2702 };
2703
2704 this.onContextMenu = function(e) {
2705 afterContextMenu = true;
2706 resetSelection(host.selection.isEmpty());
2707 host._emit("nativecontextmenu", {target: host, domEvent: e});
2708 this.moveToMouse(e, true);
2709 };
2710
2711 this.moveToMouse = function(e, bringToFront) {
2712 if (!tempStyle)
2713 tempStyle = text.style.cssText;
2714 text.style.cssText = (bringToFront ? "z-index:100000;" : "")
2715 + "height:" + text.style.height + ";"
2716 + (useragent.isIE ? "opacity:0.1;" : "");
2717
2718 var rect = host.container.getBoundingClientRect();
2719 var style = dom.computedStyle(host.container);
2720 var top = rect.top + (parseInt(style.borderTopWidth) || 0);
2721 var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
2722 var maxTop = rect.bottom - top - text.clientHeight -2;
2723 var move = function(e) {
2724 text.style.left = e.clientX - left - 2 + "px";
2725 text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
2726 };
2727 move(e);
2728
2729 if (e.type != "mousedown")
2730 return;
2731
2732 if (host.renderer.$keepTextAreaAtCursor)
2733 host.renderer.$keepTextAreaAtCursor = null;
2734
2735 clearTimeout(closeTimeout);
2736 if (useragent.isWin)
2737 event.capture(host.container, move, onContextMenuClose);
2738 };
2739
2740 this.onContextMenuClose = onContextMenuClose;
2741 var closeTimeout;
2742 function onContextMenuClose() {
2743 clearTimeout(closeTimeout);
2744 closeTimeout = setTimeout(function () {
2745 if (tempStyle) {
2746 text.style.cssText = tempStyle;
2747 tempStyle = '';
2748 }
2749 if (host.renderer.$keepTextAreaAtCursor == null) {
2750 host.renderer.$keepTextAreaAtCursor = true;
2751 host.renderer.$moveTextAreaToCursor();
2752 }
2753 }, 0);
2754 }
2755
2756 var onContextMenu = function(e) {
2757 host.textInput.onContextMenu(e);
2758 onContextMenuClose();
2759 };
2760 event.addListener(text, "mouseup", onContextMenu);
2761 event.addListener(text, "mousedown", function(e) {
2762 e.preventDefault();
2763 onContextMenuClose();
2764 });
2765 event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
2766 event.addListener(text, "contextmenu", onContextMenu);
2767};
2768
2769exports.TextInput = TextInput;
2770});
2771
2772ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
2773
2774acequire("../lib/dom");
2775acequire("../lib/event");
2776var useragent = acequire("../lib/useragent");
2777
2778var DRAG_OFFSET = 0; // pixels
2779var SCROLL_COOLDOWN_T = 250; // milliseconds
2780
2781function DefaultHandlers(mouseHandler) {
2782 mouseHandler.$clickSelection = null;
2783
2784 var editor = mouseHandler.editor;
2785 editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
2786 editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
2787 editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
2788 editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
2789 editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
2790 editor.setDefaultHandler("touchmove", this.onTouchMove.bind(mouseHandler));
2791
2792 var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd",
2793 "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"];
2794
2795 exports.forEach(function(x) {
2796 mouseHandler[x] = this[x];
2797 }, this);
2798
2799 mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
2800 mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
2801}
2802
2803(function() {
2804
2805 this.onMouseDown = function(ev) {
2806 var inSelection = ev.inSelection();
2807 var pos = ev.getDocumentPosition();
2808 this.mousedownEvent = ev;
2809 var editor = this.editor;
2810
2811 var button = ev.getButton();
2812 if (button !== 0) {
2813 var selectionRange = editor.getSelectionRange();
2814 var selectionEmpty = selectionRange.isEmpty();
2815 editor.$blockScrolling++;
2816 if (selectionEmpty || button == 1)
2817 editor.selection.moveToPosition(pos);
2818 editor.$blockScrolling--;
2819 if (button == 2) {
2820 editor.textInput.onContextMenu(ev.domEvent);
2821 if (!useragent.isMozilla)
2822 ev.preventDefault();
2823 }
2824 return;
2825 }
2826
2827 this.mousedownEvent.time = Date.now();
2828 if (inSelection && !editor.isFocused()) {
2829 editor.focus();
2830 if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
2831 this.setState("focusWait");
2832 this.captureMouse(ev);
2833 return;
2834 }
2835 }
2836
2837 this.captureMouse(ev);
2838 this.startSelect(pos, ev.domEvent._clicks > 1);
2839 return ev.preventDefault();
2840 };
2841
2842 this.startSelect = function(pos, waitForClickSelection) {
2843 pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
2844 var editor = this.editor;
2845 editor.$blockScrolling++;
2846 if (this.mousedownEvent.getShiftKey())
2847 editor.selection.selectToPosition(pos);
2848 else if (!waitForClickSelection)
2849 editor.selection.moveToPosition(pos);
2850 if (!waitForClickSelection)
2851 this.select();
2852 if (editor.renderer.scroller.setCapture) {
2853 editor.renderer.scroller.setCapture();
2854 }
2855 editor.setStyle("ace_selecting");
2856 this.setState("select");
2857 editor.$blockScrolling--;
2858 };
2859
2860 this.select = function() {
2861 var anchor, editor = this.editor;
2862 var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
2863 editor.$blockScrolling++;
2864 if (this.$clickSelection) {
2865 var cmp = this.$clickSelection.comparePoint(cursor);
2866
2867 if (cmp == -1) {
2868 anchor = this.$clickSelection.end;
2869 } else if (cmp == 1) {
2870 anchor = this.$clickSelection.start;
2871 } else {
2872 var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
2873 cursor = orientedRange.cursor;
2874 anchor = orientedRange.anchor;
2875 }
2876 editor.selection.setSelectionAnchor(anchor.row, anchor.column);
2877 }
2878 editor.selection.selectToPosition(cursor);
2879 editor.$blockScrolling--;
2880 editor.renderer.scrollCursorIntoView();
2881 };
2882
2883 this.extendSelectionBy = function(unitName) {
2884 var anchor, editor = this.editor;
2885 var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
2886 var range = editor.selection[unitName](cursor.row, cursor.column);
2887 editor.$blockScrolling++;
2888 if (this.$clickSelection) {
2889 var cmpStart = this.$clickSelection.comparePoint(range.start);
2890 var cmpEnd = this.$clickSelection.comparePoint(range.end);
2891
2892 if (cmpStart == -1 && cmpEnd <= 0) {
2893 anchor = this.$clickSelection.end;
2894 if (range.end.row != cursor.row || range.end.column != cursor.column)
2895 cursor = range.start;
2896 } else if (cmpEnd == 1 && cmpStart >= 0) {
2897 anchor = this.$clickSelection.start;
2898 if (range.start.row != cursor.row || range.start.column != cursor.column)
2899 cursor = range.end;
2900 } else if (cmpStart == -1 && cmpEnd == 1) {
2901 cursor = range.end;
2902 anchor = range.start;
2903 } else {
2904 var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
2905 cursor = orientedRange.cursor;
2906 anchor = orientedRange.anchor;
2907 }
2908 editor.selection.setSelectionAnchor(anchor.row, anchor.column);
2909 }
2910 editor.selection.selectToPosition(cursor);
2911 editor.$blockScrolling--;
2912 editor.renderer.scrollCursorIntoView();
2913 };
2914
2915 this.selectEnd =
2916 this.selectAllEnd =
2917 this.selectByWordsEnd =
2918 this.selectByLinesEnd = function() {
2919 this.$clickSelection = null;
2920 this.editor.unsetStyle("ace_selecting");
2921 if (this.editor.renderer.scroller.releaseCapture) {
2922 this.editor.renderer.scroller.releaseCapture();
2923 }
2924 };
2925
2926 this.focusWait = function() {
2927 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
2928 var time = Date.now();
2929
2930 if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
2931 this.startSelect(this.mousedownEvent.getDocumentPosition());
2932 };
2933
2934 this.onDoubleClick = function(ev) {
2935 var pos = ev.getDocumentPosition();
2936 var editor = this.editor;
2937 var session = editor.session;
2938
2939 var range = session.getBracketRange(pos);
2940 if (range) {
2941 if (range.isEmpty()) {
2942 range.start.column--;
2943 range.end.column++;
2944 }
2945 this.setState("select");
2946 } else {
2947 range = editor.selection.getWordRange(pos.row, pos.column);
2948 this.setState("selectByWords");
2949 }
2950 this.$clickSelection = range;
2951 this.select();
2952 };
2953
2954 this.onTripleClick = function(ev) {
2955 var pos = ev.getDocumentPosition();
2956 var editor = this.editor;
2957
2958 this.setState("selectByLines");
2959 var range = editor.getSelectionRange();
2960 if (range.isMultiLine() && range.contains(pos.row, pos.column)) {
2961 this.$clickSelection = editor.selection.getLineRange(range.start.row);
2962 this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;
2963 } else {
2964 this.$clickSelection = editor.selection.getLineRange(pos.row);
2965 }
2966 this.select();
2967 };
2968
2969 this.onQuadClick = function(ev) {
2970 var editor = this.editor;
2971
2972 editor.selectAll();
2973 this.$clickSelection = editor.getSelectionRange();
2974 this.setState("selectAll");
2975 };
2976
2977 this.onMouseWheel = function(ev) {
2978 if (ev.getAccelKey())
2979 return;
2980 if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {
2981 ev.wheelX = ev.wheelY;
2982 ev.wheelY = 0;
2983 }
2984
2985 var editor = this.editor;
2986
2987 if (!this.$lastScroll)
2988 this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 };
2989
2990 var prevScroll = this.$lastScroll;
2991 var t = ev.domEvent.timeStamp;
2992 var dt = t - prevScroll.t;
2993 var vx = ev.wheelX / dt;
2994 var vy = ev.wheelY / dt;
2995 if (dt < SCROLL_COOLDOWN_T) {
2996 vx = (vx + prevScroll.vx) / 2;
2997 vy = (vy + prevScroll.vy) / 2;
2998 }
2999
3000 var direction = Math.abs(vx / vy);
3001
3002 var canScroll = false;
3003 if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0))
3004 canScroll = true;
3005 if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed))
3006 canScroll = true;
3007
3008 if (canScroll) {
3009 prevScroll.allowed = t;
3010 } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) {
3011 var isSlower = Math.abs(vx) <= 1.1 * Math.abs(prevScroll.vx)
3012 && Math.abs(vy) <= 1.1 * Math.abs(prevScroll.vy);
3013 if (isSlower) {
3014 canScroll = true;
3015 prevScroll.allowed = t;
3016 }
3017 else {
3018 prevScroll.allowed = 0;
3019 }
3020 }
3021
3022 prevScroll.t = t;
3023 prevScroll.vx = vx;
3024 prevScroll.vy = vy;
3025
3026 if (canScroll) {
3027 editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
3028 return ev.stop();
3029 }
3030 };
3031
3032 this.onTouchMove = function(ev) {
3033 this.editor._emit("mousewheel", ev);
3034 };
3035
3036}).call(DefaultHandlers.prototype);
3037
3038exports.DefaultHandlers = DefaultHandlers;
3039
3040function calcDistance(ax, ay, bx, by) {
3041 return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
3042}
3043
3044function calcRangeOrientation(range, cursor) {
3045 if (range.start.row == range.end.row)
3046 var cmp = 2 * cursor.column - range.start.column - range.end.column;
3047 else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)
3048 var cmp = cursor.column - 4;
3049 else
3050 var cmp = 2 * cursor.row - range.start.row - range.end.row;
3051
3052 if (cmp < 0)
3053 return {cursor: range.start, anchor: range.end};
3054 else
3055 return {cursor: range.end, anchor: range.start};
3056}
3057
3058});
3059
3060ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(acequire, exports, module) {
3061
3062acequire("./lib/oop");
3063var dom = acequire("./lib/dom");
3064function Tooltip (parentNode) {
3065 this.isOpen = false;
3066 this.$element = null;
3067 this.$parentNode = parentNode;
3068}
3069
3070(function() {
3071 this.$init = function() {
3072 this.$element = dom.createElement("div");
3073 this.$element.className = "ace_tooltip";
3074 this.$element.style.display = "none";
3075 this.$parentNode.appendChild(this.$element);
3076 return this.$element;
3077 };
3078 this.getElement = function() {
3079 return this.$element || this.$init();
3080 };
3081 this.setText = function(text) {
3082 dom.setInnerText(this.getElement(), text);
3083 };
3084 this.setHtml = function(html) {
3085 this.getElement().innerHTML = html;
3086 };
3087 this.setPosition = function(x, y) {
3088 this.getElement().style.left = x + "px";
3089 this.getElement().style.top = y + "px";
3090 };
3091 this.setClassName = function(className) {
3092 dom.addCssClass(this.getElement(), className);
3093 };
3094 this.show = function(text, x, y) {
3095 if (text != null)
3096 this.setText(text);
3097 if (x != null && y != null)
3098 this.setPosition(x, y);
3099 if (!this.isOpen) {
3100 this.getElement().style.display = "block";
3101 this.isOpen = true;
3102 }
3103 };
3104
3105 this.hide = function() {
3106 if (this.isOpen) {
3107 this.getElement().style.display = "none";
3108 this.isOpen = false;
3109 }
3110 };
3111 this.getHeight = function() {
3112 return this.getElement().offsetHeight;
3113 };
3114 this.getWidth = function() {
3115 return this.getElement().offsetWidth;
3116 };
3117
3118 this.destroy = function() {
3119 this.isOpen = false;
3120 if (this.$element && this.$element.parentNode) {
3121 this.$element.parentNode.removeChild(this.$element);
3122 }
3123 };
3124
3125}).call(Tooltip.prototype);
3126
3127exports.Tooltip = Tooltip;
3128});
3129
3130ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(acequire, exports, module) {
3131var dom = acequire("../lib/dom");
3132var oop = acequire("../lib/oop");
3133var event = acequire("../lib/event");
3134var Tooltip = acequire("../tooltip").Tooltip;
3135
3136function GutterHandler(mouseHandler) {
3137 var editor = mouseHandler.editor;
3138 var gutter = editor.renderer.$gutterLayer;
3139 var tooltip = new GutterTooltip(editor.container);
3140
3141 mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
3142 if (!editor.isFocused() || e.getButton() != 0)
3143 return;
3144 var gutterRegion = gutter.getRegion(e);
3145
3146 if (gutterRegion == "foldWidgets")
3147 return;
3148
3149 var row = e.getDocumentPosition().row;
3150 var selection = editor.session.selection;
3151
3152 if (e.getShiftKey())
3153 selection.selectTo(row, 0);
3154 else {
3155 if (e.domEvent.detail == 2) {
3156 editor.selectAll();
3157 return e.preventDefault();
3158 }
3159 mouseHandler.$clickSelection = editor.selection.getLineRange(row);
3160 }
3161 mouseHandler.setState("selectByLines");
3162 mouseHandler.captureMouse(e);
3163 return e.preventDefault();
3164 });
3165
3166
3167 var tooltipTimeout, mouseEvent, tooltipAnnotation;
3168
3169 function showTooltip() {
3170 var row = mouseEvent.getDocumentPosition().row;
3171 var annotation = gutter.$annotations[row];
3172 if (!annotation)
3173 return hideTooltip();
3174
3175 var maxRow = editor.session.getLength();
3176 if (row == maxRow) {
3177 var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
3178 var pos = mouseEvent.$pos;
3179 if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
3180 return hideTooltip();
3181 }
3182
3183 if (tooltipAnnotation == annotation)
3184 return;
3185 tooltipAnnotation = annotation.text.join("<br/>");
3186
3187 tooltip.setHtml(tooltipAnnotation);
3188 tooltip.show();
3189 editor._signal("showGutterTooltip", tooltip);
3190 editor.on("mousewheel", hideTooltip);
3191
3192 if (mouseHandler.$tooltipFollowsMouse) {
3193 moveTooltip(mouseEvent);
3194 } else {
3195 var gutterElement = mouseEvent.domEvent.target;
3196 var rect = gutterElement.getBoundingClientRect();
3197 var style = tooltip.getElement().style;
3198 style.left = rect.right + "px";
3199 style.top = rect.bottom + "px";
3200 }
3201 }
3202
3203 function hideTooltip() {
3204 if (tooltipTimeout)
3205 tooltipTimeout = clearTimeout(tooltipTimeout);
3206 if (tooltipAnnotation) {
3207 tooltip.hide();
3208 tooltipAnnotation = null;
3209 editor._signal("hideGutterTooltip", tooltip);
3210 editor.removeEventListener("mousewheel", hideTooltip);
3211 }
3212 }
3213
3214 function moveTooltip(e) {
3215 tooltip.setPosition(e.x, e.y);
3216 }
3217
3218 mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
3219 var target = e.domEvent.target || e.domEvent.srcElement;
3220 if (dom.hasCssClass(target, "ace_fold-widget"))
3221 return hideTooltip();
3222
3223 if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)
3224 moveTooltip(e);
3225
3226 mouseEvent = e;
3227 if (tooltipTimeout)
3228 return;
3229 tooltipTimeout = setTimeout(function() {
3230 tooltipTimeout = null;
3231 if (mouseEvent && !mouseHandler.isMousePressed)
3232 showTooltip();
3233 else
3234 hideTooltip();
3235 }, 50);
3236 });
3237
3238 event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
3239 mouseEvent = null;
3240 if (!tooltipAnnotation || tooltipTimeout)
3241 return;
3242
3243 tooltipTimeout = setTimeout(function() {
3244 tooltipTimeout = null;
3245 hideTooltip();
3246 }, 50);
3247 });
3248
3249 editor.on("changeSession", hideTooltip);
3250}
3251
3252function GutterTooltip(parentNode) {
3253 Tooltip.call(this, parentNode);
3254}
3255
3256oop.inherits(GutterTooltip, Tooltip);
3257
3258(function(){
3259 this.setPosition = function(x, y) {
3260 var windowWidth = window.innerWidth || document.documentElement.clientWidth;
3261 var windowHeight = window.innerHeight || document.documentElement.clientHeight;
3262 var width = this.getWidth();
3263 var height = this.getHeight();
3264 x += 15;
3265 y += 15;
3266 if (x + width > windowWidth) {
3267 x -= (x + width) - windowWidth;
3268 }
3269 if (y + height > windowHeight) {
3270 y -= 20 + height;
3271 }
3272 Tooltip.prototype.setPosition.call(this, x, y);
3273 };
3274
3275}).call(GutterTooltip.prototype);
3276
3277
3278
3279exports.GutterHandler = GutterHandler;
3280
3281});
3282
3283ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
3284
3285var event = acequire("../lib/event");
3286var useragent = acequire("../lib/useragent");
3287var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
3288 this.domEvent = domEvent;
3289 this.editor = editor;
3290
3291 this.x = this.clientX = domEvent.clientX;
3292 this.y = this.clientY = domEvent.clientY;
3293
3294 this.$pos = null;
3295 this.$inSelection = null;
3296
3297 this.propagationStopped = false;
3298 this.defaultPrevented = false;
3299};
3300
3301(function() {
3302
3303 this.stopPropagation = function() {
3304 event.stopPropagation(this.domEvent);
3305 this.propagationStopped = true;
3306 };
3307
3308 this.preventDefault = function() {
3309 event.preventDefault(this.domEvent);
3310 this.defaultPrevented = true;
3311 };
3312
3313 this.stop = function() {
3314 this.stopPropagation();
3315 this.preventDefault();
3316 };
3317 this.getDocumentPosition = function() {
3318 if (this.$pos)
3319 return this.$pos;
3320
3321 this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
3322 return this.$pos;
3323 };
3324 this.inSelection = function() {
3325 if (this.$inSelection !== null)
3326 return this.$inSelection;
3327
3328 var editor = this.editor;
3329
3330
3331 var selectionRange = editor.getSelectionRange();
3332 if (selectionRange.isEmpty())
3333 this.$inSelection = false;
3334 else {
3335 var pos = this.getDocumentPosition();
3336 this.$inSelection = selectionRange.contains(pos.row, pos.column);
3337 }
3338
3339 return this.$inSelection;
3340 };
3341 this.getButton = function() {
3342 return event.getButton(this.domEvent);
3343 };
3344 this.getShiftKey = function() {
3345 return this.domEvent.shiftKey;
3346 };
3347
3348 this.getAccelKey = useragent.isMac
3349 ? function() { return this.domEvent.metaKey; }
3350 : function() { return this.domEvent.ctrlKey; };
3351
3352}).call(MouseEvent.prototype);
3353
3354});
3355
3356ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
3357
3358var dom = acequire("../lib/dom");
3359var event = acequire("../lib/event");
3360var useragent = acequire("../lib/useragent");
3361
3362var AUTOSCROLL_DELAY = 200;
3363var SCROLL_CURSOR_DELAY = 200;
3364var SCROLL_CURSOR_HYSTERESIS = 5;
3365
3366function DragdropHandler(mouseHandler) {
3367
3368 var editor = mouseHandler.editor;
3369
3370 var blankImage = dom.createElement("img");
3371 blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
3372 if (useragent.isOpera)
3373 blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;";
3374
3375 var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"];
3376
3377 exports.forEach(function(x) {
3378 mouseHandler[x] = this[x];
3379 }, this);
3380 editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler));
3381
3382
3383 var mouseTarget = editor.container;
3384 var dragSelectionMarker, x, y;
3385 var timerId, range;
3386 var dragCursor, counter = 0;
3387 var dragOperation;
3388 var isInternal;
3389 var autoScrollStartTime;
3390 var cursorMovedTime;
3391 var cursorPointOnCaretMoved;
3392
3393 this.onDragStart = function(e) {
3394 if (this.cancelDrag || !mouseTarget.draggable) {
3395 var self = this;
3396 setTimeout(function(){
3397 self.startSelect();
3398 self.captureMouse(e);
3399 }, 0);
3400 return e.preventDefault();
3401 }
3402 range = editor.getSelectionRange();
3403
3404 var dataTransfer = e.dataTransfer;
3405 dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove";
3406 if (useragent.isOpera) {
3407 editor.container.appendChild(blankImage);
3408 blankImage.scrollTop = 0;
3409 }
3410 dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0);
3411 if (useragent.isOpera) {
3412 editor.container.removeChild(blankImage);
3413 }
3414 dataTransfer.clearData();
3415 dataTransfer.setData("Text", editor.session.getTextRange());
3416
3417 isInternal = true;
3418 this.setState("drag");
3419 };
3420
3421 this.onDragEnd = function(e) {
3422 mouseTarget.draggable = false;
3423 isInternal = false;
3424 this.setState(null);
3425 if (!editor.getReadOnly()) {
3426 var dropEffect = e.dataTransfer.dropEffect;
3427 if (!dragOperation && dropEffect == "move")
3428 editor.session.remove(editor.getSelectionRange());
3429 editor.renderer.$cursorLayer.setBlinking(true);
3430 }
3431 this.editor.unsetStyle("ace_dragging");
3432 this.editor.renderer.setCursorStyle("");
3433 };
3434
3435 this.onDragEnter = function(e) {
3436 if (editor.getReadOnly() || !canAccept(e.dataTransfer))
3437 return;
3438 x = e.clientX;
3439 y = e.clientY;
3440 if (!dragSelectionMarker)
3441 addDragMarker();
3442 counter++;
3443 e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
3444 return event.preventDefault(e);
3445 };
3446
3447 this.onDragOver = function(e) {
3448 if (editor.getReadOnly() || !canAccept(e.dataTransfer))
3449 return;
3450 x = e.clientX;
3451 y = e.clientY;
3452 if (!dragSelectionMarker) {
3453 addDragMarker();
3454 counter++;
3455 }
3456 if (onMouseMoveTimer !== null)
3457 onMouseMoveTimer = null;
3458
3459 e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
3460 return event.preventDefault(e);
3461 };
3462
3463 this.onDragLeave = function(e) {
3464 counter--;
3465 if (counter <= 0 && dragSelectionMarker) {
3466 clearDragMarker();
3467 dragOperation = null;
3468 return event.preventDefault(e);
3469 }
3470 };
3471
3472 this.onDrop = function(e) {
3473 if (!dragCursor)
3474 return;
3475 var dataTransfer = e.dataTransfer;
3476 if (isInternal) {
3477 switch (dragOperation) {
3478 case "move":
3479 if (range.contains(dragCursor.row, dragCursor.column)) {
3480 range = {
3481 start: dragCursor,
3482 end: dragCursor
3483 };
3484 } else {
3485 range = editor.moveText(range, dragCursor);
3486 }
3487 break;
3488 case "copy":
3489 range = editor.moveText(range, dragCursor, true);
3490 break;
3491 }
3492 } else {
3493 var dropData = dataTransfer.getData('Text');
3494 range = {
3495 start: dragCursor,
3496 end: editor.session.insert(dragCursor, dropData)
3497 };
3498 editor.focus();
3499 dragOperation = null;
3500 }
3501 clearDragMarker();
3502 return event.preventDefault(e);
3503 };
3504
3505 event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler));
3506 event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler));
3507 event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler));
3508 event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler));
3509 event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler));
3510 event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler));
3511
3512 function scrollCursorIntoView(cursor, prevCursor) {
3513 var now = Date.now();
3514 var vMovement = !prevCursor || cursor.row != prevCursor.row;
3515 var hMovement = !prevCursor || cursor.column != prevCursor.column;
3516 if (!cursorMovedTime || vMovement || hMovement) {
3517 editor.$blockScrolling += 1;
3518 editor.moveCursorToPosition(cursor);
3519 editor.$blockScrolling -= 1;
3520 cursorMovedTime = now;
3521 cursorPointOnCaretMoved = {x: x, y: y};
3522 } else {
3523 var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y);
3524 if (distance > SCROLL_CURSOR_HYSTERESIS) {
3525 cursorMovedTime = null;
3526 } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) {
3527 editor.renderer.scrollCursorIntoView();
3528 cursorMovedTime = null;
3529 }
3530 }
3531 }
3532
3533 function autoScroll(cursor, prevCursor) {
3534 var now = Date.now();
3535 var lineHeight = editor.renderer.layerConfig.lineHeight;
3536 var characterWidth = editor.renderer.layerConfig.characterWidth;
3537 var editorRect = editor.renderer.scroller.getBoundingClientRect();
3538 var offsets = {
3539 x: {
3540 left: x - editorRect.left,
3541 right: editorRect.right - x
3542 },
3543 y: {
3544 top: y - editorRect.top,
3545 bottom: editorRect.bottom - y
3546 }
3547 };
3548 var nearestXOffset = Math.min(offsets.x.left, offsets.x.right);
3549 var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom);
3550 var scrollCursor = {row: cursor.row, column: cursor.column};
3551 if (nearestXOffset / characterWidth <= 2) {
3552 scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2);
3553 }
3554 if (nearestYOffset / lineHeight <= 1) {
3555 scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1);
3556 }
3557 var vScroll = cursor.row != scrollCursor.row;
3558 var hScroll = cursor.column != scrollCursor.column;
3559 var vMovement = !prevCursor || cursor.row != prevCursor.row;
3560 if (vScroll || (hScroll && !vMovement)) {
3561 if (!autoScrollStartTime)
3562 autoScrollStartTime = now;
3563 else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY)
3564 editor.renderer.scrollCursorIntoView(scrollCursor);
3565 } else {
3566 autoScrollStartTime = null;
3567 }
3568 }
3569
3570 function onDragInterval() {
3571 var prevCursor = dragCursor;
3572 dragCursor = editor.renderer.screenToTextCoordinates(x, y);
3573 scrollCursorIntoView(dragCursor, prevCursor);
3574 autoScroll(dragCursor, prevCursor);
3575 }
3576
3577 function addDragMarker() {
3578 range = editor.selection.toOrientedRange();
3579 dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
3580 editor.clearSelection();
3581 if (editor.isFocused())
3582 editor.renderer.$cursorLayer.setBlinking(false);
3583 clearInterval(timerId);
3584 onDragInterval();
3585 timerId = setInterval(onDragInterval, 20);
3586 counter = 0;
3587 event.addListener(document, "mousemove", onMouseMove);
3588 }
3589
3590 function clearDragMarker() {
3591 clearInterval(timerId);
3592 editor.session.removeMarker(dragSelectionMarker);
3593 dragSelectionMarker = null;
3594 editor.$blockScrolling += 1;
3595 editor.selection.fromOrientedRange(range);
3596 editor.$blockScrolling -= 1;
3597 if (editor.isFocused() && !isInternal)
3598 editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly());
3599 range = null;
3600 dragCursor = null;
3601 counter = 0;
3602 autoScrollStartTime = null;
3603 cursorMovedTime = null;
3604 event.removeListener(document, "mousemove", onMouseMove);
3605 }
3606 var onMouseMoveTimer = null;
3607 function onMouseMove() {
3608 if (onMouseMoveTimer == null) {
3609 onMouseMoveTimer = setTimeout(function() {
3610 if (onMouseMoveTimer != null && dragSelectionMarker)
3611 clearDragMarker();
3612 }, 20);
3613 }
3614 }
3615
3616 function canAccept(dataTransfer) {
3617 var types = dataTransfer.types;
3618 return !types || Array.prototype.some.call(types, function(type) {
3619 return type == 'text/plain' || type == 'Text';
3620 });
3621 }
3622
3623 function getDropEffect(e) {
3624 var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];
3625 var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];
3626
3627 var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey;
3628 var effectAllowed = "uninitialized";
3629 try {
3630 effectAllowed = e.dataTransfer.effectAllowed.toLowerCase();
3631 } catch (e) {}
3632 var dropEffect = "none";
3633
3634 if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0)
3635 dropEffect = "copy";
3636 else if (moveAllowed.indexOf(effectAllowed) >= 0)
3637 dropEffect = "move";
3638 else if (copyAllowed.indexOf(effectAllowed) >= 0)
3639 dropEffect = "copy";
3640
3641 return dropEffect;
3642 }
3643}
3644
3645(function() {
3646
3647 this.dragWait = function() {
3648 var interval = Date.now() - this.mousedownEvent.time;
3649 if (interval > this.editor.getDragDelay())
3650 this.startDrag();
3651 };
3652
3653 this.dragWaitEnd = function() {
3654 var target = this.editor.container;
3655 target.draggable = false;
3656 this.startSelect(this.mousedownEvent.getDocumentPosition());
3657 this.selectEnd();
3658 };
3659
3660 this.dragReadyEnd = function(e) {
3661 this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly());
3662 this.editor.unsetStyle("ace_dragging");
3663 this.editor.renderer.setCursorStyle("");
3664 this.dragWaitEnd();
3665 };
3666
3667 this.startDrag = function(){
3668 this.cancelDrag = false;
3669 var editor = this.editor;
3670 var target = editor.container;
3671 target.draggable = true;
3672 editor.renderer.$cursorLayer.setBlinking(false);
3673 editor.setStyle("ace_dragging");
3674 var cursorStyle = useragent.isWin ? "default" : "move";
3675 editor.renderer.setCursorStyle(cursorStyle);
3676 this.setState("dragReady");
3677 };
3678
3679 this.onMouseDrag = function(e) {
3680 var target = this.editor.container;
3681 if (useragent.isIE && this.state == "dragReady") {
3682 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3683 if (distance > 3)
3684 target.dragDrop();
3685 }
3686 if (this.state === "dragWait") {
3687 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3688 if (distance > 0) {
3689 target.draggable = false;
3690 this.startSelect(this.mousedownEvent.getDocumentPosition());
3691 }
3692 }
3693 };
3694
3695 this.onMouseDown = function(e) {
3696 if (!this.$dragEnabled)
3697 return;
3698 this.mousedownEvent = e;
3699 var editor = this.editor;
3700
3701 var inSelection = e.inSelection();
3702 var button = e.getButton();
3703 var clickCount = e.domEvent.detail || 1;
3704 if (clickCount === 1 && button === 0 && inSelection) {
3705 if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey()))
3706 return;
3707 this.mousedownEvent.time = Date.now();
3708 var eventTarget = e.domEvent.target || e.domEvent.srcElement;
3709 if ("unselectable" in eventTarget)
3710 eventTarget.unselectable = "on";
3711 if (editor.getDragDelay()) {
3712 if (useragent.isWebKit) {
3713 this.cancelDrag = true;
3714 var mouseTarget = editor.container;
3715 mouseTarget.draggable = true;
3716 }
3717 this.setState("dragWait");
3718 } else {
3719 this.startDrag();
3720 }
3721 this.captureMouse(e, this.onMouseDrag.bind(this));
3722 e.defaultPrevented = true;
3723 }
3724 };
3725
3726}).call(DragdropHandler.prototype);
3727
3728
3729function calcDistance(ax, ay, bx, by) {
3730 return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
3731}
3732
3733exports.DragdropHandler = DragdropHandler;
3734
3735});
3736
3737ace.define("ace/lib/net",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) {
3738var dom = acequire("./dom");
3739
3740exports.get = function (url, callback) {
3741 var xhr = new XMLHttpRequest();
3742 xhr.open('GET', url, true);
3743 xhr.onreadystatechange = function () {
3744 if (xhr.readyState === 4) {
3745 callback(xhr.responseText);
3746 }
3747 };
3748 xhr.send(null);
3749};
3750
3751exports.loadScript = function(path, callback) {
3752 var head = dom.getDocumentHead();
3753 var s = document.createElement('script');
3754
3755 s.src = path;
3756 head.appendChild(s);
3757
3758 s.onload = s.onreadystatechange = function(_, isAbort) {
3759 if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
3760 s = s.onload = s.onreadystatechange = null;
3761 if (!isAbort)
3762 callback();
3763 }
3764 };
3765};
3766exports.qualifyURL = function(url) {
3767 var a = document.createElement('a');
3768 a.href = url;
3769 return a.href;
3770};
3771
3772});
3773
3774ace.define("ace/lib/event_emitter",["require","exports","module"], function(acequire, exports, module) {
3775
3776var EventEmitter = {};
3777var stopPropagation = function() { this.propagationStopped = true; };
3778var preventDefault = function() { this.defaultPrevented = true; };
3779
3780EventEmitter._emit =
3781EventEmitter._dispatchEvent = function(eventName, e) {
3782 this._eventRegistry || (this._eventRegistry = {});
3783 this._defaultHandlers || (this._defaultHandlers = {});
3784
3785 var listeners = this._eventRegistry[eventName] || [];
3786 var defaultHandler = this._defaultHandlers[eventName];
3787 if (!listeners.length && !defaultHandler)
3788 return;
3789
3790 if (typeof e != "object" || !e)
3791 e = {};
3792
3793 if (!e.type)
3794 e.type = eventName;
3795 if (!e.stopPropagation)
3796 e.stopPropagation = stopPropagation;
3797 if (!e.preventDefault)
3798 e.preventDefault = preventDefault;
3799
3800 listeners = listeners.slice();
3801 for (var i=0; i<listeners.length; i++) {
3802 listeners[i](e, this);
3803 if (e.propagationStopped)
3804 break;
3805 }
3806
3807 if (defaultHandler && !e.defaultPrevented)
3808 return defaultHandler(e, this);
3809};
3810
3811
3812EventEmitter._signal = function(eventName, e) {
3813 var listeners = (this._eventRegistry || {})[eventName];
3814 if (!listeners)
3815 return;
3816 listeners = listeners.slice();
3817 for (var i=0; i<listeners.length; i++)
3818 listeners[i](e, this);
3819};
3820
3821EventEmitter.once = function(eventName, callback) {
3822 var _self = this;
3823 callback && this.addEventListener(eventName, function newCallback() {
3824 _self.removeEventListener(eventName, newCallback);
3825 callback.apply(null, arguments);
3826 });
3827};
3828
3829
3830EventEmitter.setDefaultHandler = function(eventName, callback) {
3831 var handlers = this._defaultHandlers;
3832 if (!handlers)
3833 handlers = this._defaultHandlers = {_disabled_: {}};
3834
3835 if (handlers[eventName]) {
3836 var old = handlers[eventName];
3837 var disabled = handlers._disabled_[eventName];
3838 if (!disabled)
3839 handlers._disabled_[eventName] = disabled = [];
3840 disabled.push(old);
3841 var i = disabled.indexOf(callback);
3842 if (i != -1)
3843 disabled.splice(i, 1);
3844 }
3845 handlers[eventName] = callback;
3846};
3847EventEmitter.removeDefaultHandler = function(eventName, callback) {
3848 var handlers = this._defaultHandlers;
3849 if (!handlers)
3850 return;
3851 var disabled = handlers._disabled_[eventName];
3852
3853 if (handlers[eventName] == callback) {
3854 handlers[eventName];
3855 if (disabled)
3856 this.setDefaultHandler(eventName, disabled.pop());
3857 } else if (disabled) {
3858 var i = disabled.indexOf(callback);
3859 if (i != -1)
3860 disabled.splice(i, 1);
3861 }
3862};
3863
3864EventEmitter.on =
3865EventEmitter.addEventListener = function(eventName, callback, capturing) {
3866 this._eventRegistry = this._eventRegistry || {};
3867
3868 var listeners = this._eventRegistry[eventName];
3869 if (!listeners)
3870 listeners = this._eventRegistry[eventName] = [];
3871
3872 if (listeners.indexOf(callback) == -1)
3873 listeners[capturing ? "unshift" : "push"](callback);
3874 return callback;
3875};
3876
3877EventEmitter.off =
3878EventEmitter.removeListener =
3879EventEmitter.removeEventListener = function(eventName, callback) {
3880 this._eventRegistry = this._eventRegistry || {};
3881
3882 var listeners = this._eventRegistry[eventName];
3883 if (!listeners)
3884 return;
3885
3886 var index = listeners.indexOf(callback);
3887 if (index !== -1)
3888 listeners.splice(index, 1);
3889};
3890
3891EventEmitter.removeAllListeners = function(eventName) {
3892 if (this._eventRegistry) this._eventRegistry[eventName] = [];
3893};
3894
3895exports.EventEmitter = EventEmitter;
3896
3897});
3898
3899ace.define("ace/lib/app_config",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(acequire, exports, module) {
3900"no use strict";
3901
3902var oop = acequire("./oop");
3903var EventEmitter = acequire("./event_emitter").EventEmitter;
3904
3905var optionsProvider = {
3906 setOptions: function(optList) {
3907 Object.keys(optList).forEach(function(key) {
3908 this.setOption(key, optList[key]);
3909 }, this);
3910 },
3911 getOptions: function(optionNames) {
3912 var result = {};
3913 if (!optionNames) {
3914 optionNames = Object.keys(this.$options);
3915 } else if (!Array.isArray(optionNames)) {
3916 result = optionNames;
3917 optionNames = Object.keys(result);
3918 }
3919 optionNames.forEach(function(key) {
3920 result[key] = this.getOption(key);
3921 }, this);
3922 return result;
3923 },
3924 setOption: function(name, value) {
3925 if (this["$" + name] === value)
3926 return;
3927 var opt = this.$options[name];
3928 if (!opt) {
3929 return warn('misspelled option "' + name + '"');
3930 }
3931 if (opt.forwardTo)
3932 return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
3933
3934 if (!opt.handlesSet)
3935 this["$" + name] = value;
3936 if (opt && opt.set)
3937 opt.set.call(this, value);
3938 },
3939 getOption: function(name) {
3940 var opt = this.$options[name];
3941 if (!opt) {
3942 return warn('misspelled option "' + name + '"');
3943 }
3944 if (opt.forwardTo)
3945 return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
3946 return opt && opt.get ? opt.get.call(this) : this["$" + name];
3947 }
3948};
3949
3950function warn(message) {
3951 if (typeof console != "undefined" && console.warn)
3952 console.warn.apply(console, arguments);
3953}
3954
3955function reportError(msg, data) {
3956 var e = new Error(msg);
3957 e.data = data;
3958 if (typeof console == "object" && console.error)
3959 console.error(e);
3960 setTimeout(function() { throw e; });
3961}
3962
3963var AppConfig = function() {
3964 this.$defaultOptions = {};
3965};
3966
3967(function() {
3968 oop.implement(this, EventEmitter);
3969 this.defineOptions = function(obj, path, options) {
3970 if (!obj.$options)
3971 this.$defaultOptions[path] = obj.$options = {};
3972
3973 Object.keys(options).forEach(function(key) {
3974 var opt = options[key];
3975 if (typeof opt == "string")
3976 opt = {forwardTo: opt};
3977
3978 opt.name || (opt.name = key);
3979 obj.$options[opt.name] = opt;
3980 if ("initialValue" in opt)
3981 obj["$" + opt.name] = opt.initialValue;
3982 });
3983 oop.implement(obj, optionsProvider);
3984
3985 return this;
3986 };
3987
3988 this.resetOptions = function(obj) {
3989 Object.keys(obj.$options).forEach(function(key) {
3990 var opt = obj.$options[key];
3991 if ("value" in opt)
3992 obj.setOption(key, opt.value);
3993 });
3994 };
3995
3996 this.setDefaultValue = function(path, name, value) {
3997 var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {});
3998 if (opts[name]) {
3999 if (opts.forwardTo)
4000 this.setDefaultValue(opts.forwardTo, name, value);
4001 else
4002 opts[name].value = value;
4003 }
4004 };
4005
4006 this.setDefaultValues = function(path, optionHash) {
4007 Object.keys(optionHash).forEach(function(key) {
4008 this.setDefaultValue(path, key, optionHash[key]);
4009 }, this);
4010 };
4011
4012 this.warn = warn;
4013 this.reportError = reportError;
4014
4015}).call(AppConfig.prototype);
4016
4017exports.AppConfig = AppConfig;
4018
4019});
4020
4021ace.define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/app_config"], function(acequire, exports, module) {
4022"no use strict";
4023
4024var lang = acequire("./lib/lang");
4025acequire("./lib/oop");
4026var net = acequire("./lib/net");
4027var AppConfig = acequire("./lib/app_config").AppConfig;
4028
4029module.exports = exports = new AppConfig();
4030
4031var global = (function() {
4032 return this || typeof window != "undefined" && window;
4033})();
4034
4035var options = {
4036 packaged: false,
4037 workerPath: null,
4038 modePath: null,
4039 themePath: null,
4040 basePath: "",
4041 suffix: ".js",
4042 $moduleUrls: {}
4043};
4044
4045exports.get = function(key) {
4046 if (!options.hasOwnProperty(key))
4047 throw new Error("Unknown config key: " + key);
4048
4049 return options[key];
4050};
4051
4052exports.set = function(key, value) {
4053 if (!options.hasOwnProperty(key))
4054 throw new Error("Unknown config key: " + key);
4055
4056 options[key] = value;
4057};
4058
4059exports.all = function() {
4060 return lang.copyObject(options);
4061};
4062exports.moduleUrl = function(name, component) {
4063 if (options.$moduleUrls[name])
4064 return options.$moduleUrls[name];
4065
4066 var parts = name.split("/");
4067 component = component || parts[parts.length - 2] || "";
4068 var sep = component == "snippets" ? "/" : "-";
4069 var base = parts[parts.length - 1];
4070 if (component == "worker" && sep == "-") {
4071 var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g");
4072 base = base.replace(re, "");
4073 }
4074
4075 if ((!base || base == component) && parts.length > 1)
4076 base = parts[parts.length - 2];
4077 var path = options[component + "Path"];
4078 if (path == null) {
4079 path = options.basePath;
4080 } else if (sep == "/") {
4081 component = sep = "";
4082 }
4083 if (path && path.slice(-1) != "/")
4084 path += "/";
4085 return path + component + sep + base + this.get("suffix");
4086};
4087
4088exports.setModuleUrl = function(name, subst) {
4089 return options.$moduleUrls[name] = subst;
4090};
4091
4092exports.$loading = {};
4093exports.loadModule = function(moduleName, onLoad) {
4094 var module, moduleType;
4095 if (Array.isArray(moduleName)) {
4096 moduleType = moduleName[0];
4097 moduleName = moduleName[1];
4098 }
4099
4100 try {
4101 module = acequire(moduleName);
4102 } catch (e) {}
4103 if (module && !exports.$loading[moduleName])
4104 return onLoad && onLoad(module);
4105
4106 if (!exports.$loading[moduleName])
4107 exports.$loading[moduleName] = [];
4108
4109 exports.$loading[moduleName].push(onLoad);
4110
4111 if (exports.$loading[moduleName].length > 1)
4112 return;
4113
4114 var afterLoad = function() {
4115 acequire([moduleName], function(module) {
4116 exports._emit("load.module", {name: moduleName, module: module});
4117 var listeners = exports.$loading[moduleName];
4118 exports.$loading[moduleName] = null;
4119 listeners.forEach(function(onLoad) {
4120 onLoad && onLoad(module);
4121 });
4122 });
4123 };
4124
4125 if (!exports.get("packaged"))
4126 return afterLoad();
4127 net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
4128};
4129init(true);function init(packaged) {
4130
4131 if (!global || !global.document)
4132 return;
4133
4134 options.packaged = packaged || acequire.packaged || module.packaged || (global.define && undefined.packaged);
4135
4136 var scriptOptions = {};
4137 var scriptUrl = "";
4138 var currentScript = (document.currentScript || document._currentScript ); // native or polyfill
4139 var currentDocument = currentScript && currentScript.ownerDocument || document;
4140
4141 var scripts = currentDocument.getElementsByTagName("script");
4142 for (var i=0; i<scripts.length; i++) {
4143 var script = scripts[i];
4144
4145 var src = script.src || script.getAttribute("src");
4146 if (!src)
4147 continue;
4148
4149 var attributes = script.attributes;
4150 for (var j=0, l=attributes.length; j < l; j++) {
4151 var attr = attributes[j];
4152 if (attr.name.indexOf("data-ace-") === 0) {
4153 scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
4154 }
4155 }
4156
4157 var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
4158 if (m)
4159 scriptUrl = m[1];
4160 }
4161
4162 if (scriptUrl) {
4163 scriptOptions.base = scriptOptions.base || scriptUrl;
4164 scriptOptions.packaged = true;
4165 }
4166
4167 scriptOptions.basePath = scriptOptions.base;
4168 scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
4169 scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
4170 scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
4171 delete scriptOptions.base;
4172
4173 for (var key in scriptOptions)
4174 if (typeof scriptOptions[key] !== "undefined")
4175 exports.set(key, scriptOptions[key]);
4176}
4177
4178exports.init = init;
4179
4180function deHyphenate(str) {
4181 return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
4182}
4183
4184});
4185
4186ace.define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"], function(acequire, exports, module) {
4187
4188var event = acequire("../lib/event");
4189var useragent = acequire("../lib/useragent");
4190var DefaultHandlers = acequire("./default_handlers").DefaultHandlers;
4191var DefaultGutterHandler = acequire("./default_gutter_handler").GutterHandler;
4192var MouseEvent = acequire("./mouse_event").MouseEvent;
4193var DragdropHandler = acequire("./dragdrop_handler").DragdropHandler;
4194var config = acequire("../config");
4195
4196var MouseHandler = function(editor) {
4197 var _self = this;
4198 this.editor = editor;
4199
4200 new DefaultHandlers(this);
4201 new DefaultGutterHandler(this);
4202 new DragdropHandler(this);
4203
4204 var focusEditor = function(e) {
4205 var windowBlurred = !document.hasFocus || !document.hasFocus()
4206 || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement());
4207 if (windowBlurred)
4208 window.focus();
4209 editor.focus();
4210 };
4211
4212 var mouseTarget = editor.renderer.getMouseEventTarget();
4213 event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
4214 event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
4215 event.addMultiMouseDownListener([
4216 mouseTarget,
4217 editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner,
4218 editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner,
4219 editor.textInput && editor.textInput.getElement()
4220 ].filter(Boolean), [400, 300, 250], this, "onMouseEvent");
4221 event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
4222 event.addTouchMoveListener(editor.container, this.onTouchMove.bind(this, "touchmove"));
4223
4224 var gutterEl = editor.renderer.$gutter;
4225 event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
4226 event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
4227 event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
4228 event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
4229
4230 event.addListener(mouseTarget, "mousedown", focusEditor);
4231 event.addListener(gutterEl, "mousedown", focusEditor);
4232 if (useragent.isIE && editor.renderer.scrollBarV) {
4233 event.addListener(editor.renderer.scrollBarV.element, "mousedown", focusEditor);
4234 event.addListener(editor.renderer.scrollBarH.element, "mousedown", focusEditor);
4235 }
4236
4237 editor.on("mousemove", function(e){
4238 if (_self.state || _self.$dragDelay || !_self.$dragEnabled)
4239 return;
4240
4241 var character = editor.renderer.screenToTextCoordinates(e.x, e.y);
4242 var range = editor.session.selection.getRange();
4243 var renderer = editor.renderer;
4244
4245 if (!range.isEmpty() && range.insideStart(character.row, character.column)) {
4246 renderer.setCursorStyle("default");
4247 } else {
4248 renderer.setCursorStyle("");
4249 }
4250 });
4251};
4252
4253(function() {
4254 this.onMouseEvent = function(name, e) {
4255 this.editor._emit(name, new MouseEvent(e, this.editor));
4256 };
4257
4258 this.onMouseMove = function(name, e) {
4259 var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
4260 if (!listeners || !listeners.length)
4261 return;
4262
4263 this.editor._emit(name, new MouseEvent(e, this.editor));
4264 };
4265
4266 this.onMouseWheel = function(name, e) {
4267 var mouseEvent = new MouseEvent(e, this.editor);
4268 mouseEvent.speed = this.$scrollSpeed * 2;
4269 mouseEvent.wheelX = e.wheelX;
4270 mouseEvent.wheelY = e.wheelY;
4271
4272 this.editor._emit(name, mouseEvent);
4273 };
4274
4275 this.onTouchMove = function (name, e) {
4276 var mouseEvent = new MouseEvent(e, this.editor);
4277 mouseEvent.speed = 1;//this.$scrollSpeed * 2;
4278 mouseEvent.wheelX = e.wheelX;
4279 mouseEvent.wheelY = e.wheelY;
4280 this.editor._emit(name, mouseEvent);
4281 };
4282
4283 this.setState = function(state) {
4284 this.state = state;
4285 };
4286
4287 this.captureMouse = function(ev, mouseMoveHandler) {
4288 this.x = ev.x;
4289 this.y = ev.y;
4290
4291 this.isMousePressed = true;
4292 var renderer = this.editor.renderer;
4293 if (renderer.$keepTextAreaAtCursor)
4294 renderer.$keepTextAreaAtCursor = null;
4295
4296 var self = this;
4297 var onMouseMove = function(e) {
4298 if (!e) return;
4299 if (useragent.isWebKit && !e.which && self.releaseMouse)
4300 return self.releaseMouse();
4301
4302 self.x = e.clientX;
4303 self.y = e.clientY;
4304 mouseMoveHandler && mouseMoveHandler(e);
4305 self.mouseEvent = new MouseEvent(e, self.editor);
4306 self.$mouseMoved = true;
4307 };
4308
4309 var onCaptureEnd = function(e) {
4310 clearInterval(timerId);
4311 onCaptureInterval();
4312 self[self.state + "End"] && self[self.state + "End"](e);
4313 self.state = "";
4314 if (renderer.$keepTextAreaAtCursor == null) {
4315 renderer.$keepTextAreaAtCursor = true;
4316 renderer.$moveTextAreaToCursor();
4317 }
4318 self.isMousePressed = false;
4319 self.$onCaptureMouseMove = self.releaseMouse = null;
4320 e && self.onMouseEvent("mouseup", e);
4321 };
4322
4323 var onCaptureInterval = function() {
4324 self[self.state] && self[self.state]();
4325 self.$mouseMoved = false;
4326 };
4327
4328 if (useragent.isOldIE && ev.domEvent.type == "dblclick") {
4329 return setTimeout(function() {onCaptureEnd(ev);});
4330 }
4331
4332 self.$onCaptureMouseMove = onMouseMove;
4333 self.releaseMouse = event.capture(this.editor.container, onMouseMove, onCaptureEnd);
4334 var timerId = setInterval(onCaptureInterval, 20);
4335 };
4336 this.releaseMouse = null;
4337 this.cancelContextMenu = function() {
4338 var stop = function(e) {
4339 if (e && e.domEvent && e.domEvent.type != "contextmenu")
4340 return;
4341 this.editor.off("nativecontextmenu", stop);
4342 if (e && e.domEvent)
4343 event.stopEvent(e.domEvent);
4344 }.bind(this);
4345 setTimeout(stop, 10);
4346 this.editor.on("nativecontextmenu", stop);
4347 };
4348}).call(MouseHandler.prototype);
4349
4350config.defineOptions(MouseHandler.prototype, "mouseHandler", {
4351 scrollSpeed: {initialValue: 2},
4352 dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},
4353 dragEnabled: {initialValue: true},
4354 focusTimout: {initialValue: 0},
4355 tooltipFollowsMouse: {initialValue: true}
4356});
4357
4358
4359exports.MouseHandler = MouseHandler;
4360});
4361
4362ace.define("ace/mouse/fold_handler",["require","exports","module"], function(acequire, exports, module) {
4363
4364function FoldHandler(editor) {
4365
4366 editor.on("click", function(e) {
4367 var position = e.getDocumentPosition();
4368 var session = editor.session;
4369 var fold = session.getFoldAt(position.row, position.column, 1);
4370 if (fold) {
4371 if (e.getAccelKey())
4372 session.removeFold(fold);
4373 else
4374 session.expandFold(fold);
4375
4376 e.stop();
4377 }
4378 });
4379
4380 editor.on("gutterclick", function(e) {
4381 var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4382
4383 if (gutterRegion == "foldWidgets") {
4384 var row = e.getDocumentPosition().row;
4385 var session = editor.session;
4386 if (session.foldWidgets && session.foldWidgets[row])
4387 editor.session.onFoldWidgetClick(row, e);
4388 if (!editor.isFocused())
4389 editor.focus();
4390 e.stop();
4391 }
4392 });
4393
4394 editor.on("gutterdblclick", function(e) {
4395 var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4396
4397 if (gutterRegion == "foldWidgets") {
4398 var row = e.getDocumentPosition().row;
4399 var session = editor.session;
4400 var data = session.getParentFoldRangeData(row, true);
4401 var range = data.range || data.firstRange;
4402
4403 if (range) {
4404 row = range.start.row;
4405 var fold = session.getFoldAt(row, session.getLine(row).length, 1);
4406
4407 if (fold) {
4408 session.removeFold(fold);
4409 } else {
4410 session.addFold("...", range);
4411 editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
4412 }
4413 }
4414 e.stop();
4415 }
4416 });
4417}
4418
4419exports.FoldHandler = FoldHandler;
4420
4421});
4422
4423ace.define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"], function(acequire, exports, module) {
4424
4425var keyUtil = acequire("../lib/keys");
4426var event = acequire("../lib/event");
4427
4428var KeyBinding = function(editor) {
4429 this.$editor = editor;
4430 this.$data = {editor: editor};
4431 this.$handlers = [];
4432 this.setDefaultHandler(editor.commands);
4433};
4434
4435(function() {
4436 this.setDefaultHandler = function(kb) {
4437 this.removeKeyboardHandler(this.$defaultHandler);
4438 this.$defaultHandler = kb;
4439 this.addKeyboardHandler(kb, 0);
4440 };
4441
4442 this.setKeyboardHandler = function(kb) {
4443 var h = this.$handlers;
4444 if (h[h.length - 1] == kb)
4445 return;
4446
4447 while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler)
4448 this.removeKeyboardHandler(h[h.length - 1]);
4449
4450 this.addKeyboardHandler(kb, 1);
4451 };
4452
4453 this.addKeyboardHandler = function(kb, pos) {
4454 if (!kb)
4455 return;
4456 if (typeof kb == "function" && !kb.handleKeyboard)
4457 kb.handleKeyboard = kb;
4458 var i = this.$handlers.indexOf(kb);
4459 if (i != -1)
4460 this.$handlers.splice(i, 1);
4461
4462 if (pos == undefined)
4463 this.$handlers.push(kb);
4464 else
4465 this.$handlers.splice(pos, 0, kb);
4466
4467 if (i == -1 && kb.attach)
4468 kb.attach(this.$editor);
4469 };
4470
4471 this.removeKeyboardHandler = function(kb) {
4472 var i = this.$handlers.indexOf(kb);
4473 if (i == -1)
4474 return false;
4475 this.$handlers.splice(i, 1);
4476 kb.detach && kb.detach(this.$editor);
4477 return true;
4478 };
4479
4480 this.getKeyboardHandler = function() {
4481 return this.$handlers[this.$handlers.length - 1];
4482 };
4483
4484 this.getStatusText = function() {
4485 var data = this.$data;
4486 var editor = data.editor;
4487 return this.$handlers.map(function(h) {
4488 return h.getStatusText && h.getStatusText(editor, data) || "";
4489 }).filter(Boolean).join(" ");
4490 };
4491
4492 this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) {
4493 var toExecute;
4494 var success = false;
4495 var commands = this.$editor.commands;
4496
4497 for (var i = this.$handlers.length; i--;) {
4498 toExecute = this.$handlers[i].handleKeyboard(
4499 this.$data, hashId, keyString, keyCode, e
4500 );
4501 if (!toExecute || !toExecute.command)
4502 continue;
4503 if (toExecute.command == "null") {
4504 success = true;
4505 } else {
4506 success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
4507 }
4508 if (success && e && hashId != -1 &&
4509 toExecute.passEvent != true && toExecute.command.passEvent != true
4510 ) {
4511 event.stopEvent(e);
4512 }
4513 if (success)
4514 break;
4515 }
4516
4517 if (!success && hashId == -1) {
4518 toExecute = {command: "insertstring"};
4519 success = commands.exec("insertstring", this.$editor, keyString);
4520 }
4521
4522 if (success && this.$editor._signal)
4523 this.$editor._signal("keyboardActivity", toExecute);
4524
4525 return success;
4526 };
4527
4528 this.onCommandKey = function(e, hashId, keyCode) {
4529 var keyString = keyUtil.keyCodeToString(keyCode);
4530 this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
4531 };
4532
4533 this.onTextInput = function(text) {
4534 this.$callKeyboardHandlers(-1, text);
4535 };
4536
4537}).call(KeyBinding.prototype);
4538
4539exports.KeyBinding = KeyBinding;
4540});
4541
4542ace.define("ace/lib/bidiutil",["require","exports","module"], function(acequire, exports, module) {
4543var dir = 0, hiLevel = 0;
4544var lastArabic = false, hasUBAT_B = false, hasUBAT_S = false;
4545
4546var impTab_LTR = [ [ 0, 3, 0, 1, 0, 0, 0 ], [ 0, 3, 0, 1, 2, 2, 0 ], [ 0, 3, 0, 0x11, 2, 0, 1 ], [ 0, 3, 5, 5, 4, 1, 0 ], [ 0, 3, 0x15, 0x15, 4, 0, 1 ], [ 0, 3, 5, 5, 4, 2, 0 ]
4547];
4548
4549var impTab_RTL = [ [ 2, 0, 1, 1, 0, 1, 0 ], [ 2, 0, 1, 1, 0, 2, 0 ], [ 2, 0, 2, 1, 3, 2, 0 ], [ 2, 0, 2, 0x21, 3, 1, 1 ]
4550];
4551
4552var LTR = 0, RTL = 1;
4553
4554var L = 0;
4555var R = 1;
4556var EN = 2;
4557var AN = 3;
4558var ON = 4;
4559var B = 5;
4560var S = 6;
4561var AL = 7;
4562var WS = 8;
4563var CS = 9;
4564var ES = 10;
4565var ET = 11;
4566var NSM = 12;
4567var LRE = 13;
4568var RLE = 14;
4569var PDF = 15;
4570var LRO = 16;
4571var RLO = 17;
4572var BN = 18;
4573
4574var UnicodeTBL00 = [
4575BN,BN,BN,BN,BN,BN,BN,BN,BN,S,B,S,WS,B,BN,BN,
4576BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,B,B,B,S,
4577WS,ON,ON,ET,ET,ET,ON,ON,ON,ON,ON,ES,CS,ES,CS,CS,
4578EN,EN,EN,EN,EN,EN,EN,EN,EN,EN,CS,ON,ON,ON,ON,ON,
4579ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,
4580L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,ON,
4581ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,
4582L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,BN,
4583BN,BN,BN,BN,BN,B,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,
4584BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,
4585CS,ON,ET,ET,ET,ET,ON,ON,ON,ON,L,ON,ON,BN,ON,ON,
4586ET,ET,EN,EN,ON,L,ON,ON,ON,EN,L,ON,ON,ON,ON,ON
4587];
4588
4589var UnicodeTBL20 = [
4590WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,BN,BN,BN,L,R ,
4591ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4592ON,ON,ON,ON,ON,ON,ON,ON,WS,B,LRE,RLE,PDF,LRO,RLO,CS,
4593ET,ET,ET,ET,ET,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4594ON,ON,ON,ON,CS,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4595ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,WS
4596];
4597
4598function _computeLevels(chars, levels, len, charTypes) {
4599 var impTab = dir ? impTab_RTL : impTab_LTR
4600 , prevState = null, newClass = null, newLevel = null, newState = 0
4601 , action = null, cond = null, condPos = -1, i = null, ix = null, classes = [];
4602
4603 if (!charTypes) {
4604 for (i = 0, charTypes = []; i < len; i++) {
4605 charTypes[i] = _getCharacterType(chars[i]);
4606 }
4607 }
4608 hiLevel = dir;
4609 lastArabic = false;
4610 hasUBAT_B = false;
4611 hasUBAT_S = false;
4612 for (ix = 0; ix < len; ix++){
4613 prevState = newState;
4614 classes[ix] = newClass = _getCharClass(chars, charTypes, classes, ix);
4615 newState = impTab[prevState][newClass];
4616 action = newState & 0xF0;
4617 newState &= 0x0F;
4618 levels[ix] = newLevel = impTab[newState][5];
4619 if (action > 0){
4620 if (action == 0x10){
4621 for(i = condPos; i < ix; i++){
4622 levels[i] = 1;
4623 }
4624 condPos = -1;
4625 } else {
4626 condPos = -1;
4627 }
4628 }
4629 cond = impTab[newState][6];
4630 if (cond){
4631 if(condPos == -1){
4632 condPos = ix;
4633 }
4634 }else {
4635 if (condPos > -1){
4636 for(i = condPos; i < ix; i++){
4637 levels[i] = newLevel;
4638 }
4639 condPos = -1;
4640 }
4641 }
4642 if (charTypes[ix] == B){
4643 levels[ix] = 0;
4644 }
4645 hiLevel |= newLevel;
4646 }
4647 if (hasUBAT_S){
4648 for(i = 0; i < len; i++){
4649 if(charTypes[i] == S){
4650 levels[i] = dir;
4651 for(var j = i - 1; j >= 0; j--){
4652 if(charTypes[j] == WS){
4653 levels[j] = dir;
4654 }else {
4655 break;
4656 }
4657 }
4658 }
4659 }
4660 }
4661}
4662
4663function _invertLevel(lev, levels, _array) {
4664 if (hiLevel < lev){
4665 return;
4666 }
4667 if (lev == 1 && dir == RTL && !hasUBAT_B){
4668 _array.reverse();
4669 return;
4670 }
4671 var len = _array.length, start = 0, end, lo, hi, tmp;
4672 while(start < len){
4673 if (levels[start] >= lev){
4674 end = start + 1;
4675 while(end < len && levels[end] >= lev){
4676 end++;
4677 }
4678 for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){
4679 tmp = _array[lo];
4680 _array[lo] = _array[hi];
4681 _array[hi] = tmp;
4682 }
4683 start = end;
4684 }
4685 start++;
4686 }
4687}
4688
4689function _getCharClass(chars, types, classes, ix) {
4690 var cType = types[ix], wType, nType, len, i;
4691 switch(cType){
4692 case L:
4693 case R:
4694 lastArabic = false;
4695 case ON:
4696 case AN:
4697 return cType;
4698 case EN:
4699 return lastArabic ? AN : EN;
4700 case AL:
4701 lastArabic = true;
4702 return R;
4703 case WS:
4704 return ON;
4705 case CS:
4706 if (ix < 1 || (ix + 1) >= types.length ||
4707 ((wType = classes[ix - 1]) != EN && wType != AN) ||
4708 ((nType = types[ix + 1]) != EN && nType != AN)){
4709 return ON;
4710 }
4711 if (lastArabic){nType = AN;}
4712 return nType == wType ? nType : ON;
4713 case ES:
4714 wType = ix > 0 ? classes[ix - 1] : B;
4715 if (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){
4716 return EN;
4717 }
4718 return ON;
4719 case ET:
4720 if (ix > 0 && classes[ix - 1] == EN){
4721 return EN;
4722 }
4723 if (lastArabic){
4724 return ON;
4725 }
4726 i = ix + 1;
4727 len = types.length;
4728 while (i < len && types[i] == ET){
4729 i++;
4730 }
4731 if (i < len && types[i] == EN){
4732 return EN;
4733 }
4734 return ON;
4735 case NSM:
4736 len = types.length;
4737 i = ix + 1;
4738 while (i < len && types[i] == NSM){
4739 i++;
4740 }
4741 if (i < len){
4742 var c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E;
4743
4744 wType = types[i];
4745 if (rtlCandidate && (wType == R || wType == AL)){
4746 return R;
4747 }
4748 }
4749
4750 if (ix < 1 || (wType = types[ix - 1]) == B){
4751 return ON;
4752 }
4753 return classes[ix - 1];
4754 case B:
4755 lastArabic = false;
4756 hasUBAT_B = true;
4757 return dir;
4758 case S:
4759 hasUBAT_S = true;
4760 return ON;
4761 case LRE:
4762 case RLE:
4763 case LRO:
4764 case RLO:
4765 case PDF:
4766 lastArabic = false;
4767 case BN:
4768 return ON;
4769 }
4770}
4771
4772function _getCharacterType( ch ) {
4773 var uc = ch.charCodeAt(0), hi = uc >> 8;
4774
4775 if (hi == 0) {
4776 return ((uc > 0x00BF) ? L : UnicodeTBL00[uc]);
4777 } else if (hi == 5) {
4778 return (/[\u0591-\u05f4]/.test(ch) ? R : L);
4779 } else if (hi == 6) {
4780 if (/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(ch))
4781 return NSM;
4782 else if (/[\u0660-\u0669\u066b-\u066c]/.test(ch))
4783 return AN;
4784 else if (uc == 0x066A)
4785 return ET;
4786 else if (/[\u06f0-\u06f9]/.test(ch))
4787 return EN;
4788 else
4789 return AL;
4790 } else if (hi == 0x20 && uc <= 0x205F) {
4791 return UnicodeTBL20[uc & 0xFF];
4792 } else if (hi == 0xFE) {
4793 return (uc >= 0xFE70 ? AL : ON);
4794 }
4795 return ON;
4796}
4797exports.L = L;
4798exports.R = R;
4799exports.EN = EN;
4800exports.ON_R = 3;
4801exports.AN = 4;
4802exports.R_H = 5;
4803exports.B = 6;
4804
4805exports.DOT = "\xB7";
4806exports.doBidiReorder = function(text, textCharTypes, isRtl) {
4807 if (text.length < 2)
4808 return {};
4809
4810 var chars = text.split(""), logicalFromVisual = new Array(chars.length),
4811 bidiLevels = new Array(chars.length), levels = [];
4812
4813 dir = isRtl ? RTL : LTR;
4814
4815 _computeLevels(chars, levels, chars.length, textCharTypes);
4816
4817 for (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++);
4818
4819 _invertLevel(2, levels, logicalFromVisual);
4820 _invertLevel(1, levels, logicalFromVisual);
4821
4822 for (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width
4823 if (textCharTypes[i] === AN) {
4824 levels[i] = exports.AN;
4825 } else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE)
4826 || textCharTypes[i] === ON || textCharTypes[i] === BN)) {
4827 levels[i] = exports.ON_R;
4828 } else if ((i > 0 && chars[i - 1] === '\u0644') && /\u0622|\u0623|\u0625|\u0627/.test(chars[i])) {
4829 levels[i - 1] = levels[i] = exports.R_H;
4830 i++;
4831 }
4832 }
4833 if (chars[chars.length - 1] === exports.DOT)
4834 levels[chars.length - 1] = exports.B;
4835
4836 for (var i = 0; i < logicalFromVisual.length; i++) {
4837 bidiLevels[i] = levels[logicalFromVisual[i]];
4838 }
4839
4840 return {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels};
4841};
4842exports.hasBidiCharacters = function(text, textCharTypes){
4843 var ret = false;
4844 for (var i = 0; i < text.length; i++){
4845 textCharTypes[i] = _getCharacterType(text.charAt(i));
4846 if (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL))
4847 ret = true;
4848 }
4849 return ret;
4850};
4851exports.getVisualFromLogicalIdx = function(logIdx, rowMap) {
4852 for (var i = 0; i < rowMap.logicalFromVisual.length; i++) {
4853 if (rowMap.logicalFromVisual[i] == logIdx)
4854 return i;
4855 }
4856 return 0;
4857};
4858
4859});
4860
4861ace.define("ace/bidihandler",["require","exports","module","ace/lib/bidiutil","ace/lib/lang","ace/lib/useragent"], function(acequire, exports, module) {
4862
4863var bidiUtil = acequire("./lib/bidiutil");
4864var lang = acequire("./lib/lang");
4865var useragent = acequire("./lib/useragent");
4866var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
4867var BidiHandler = function(session) {
4868 this.session = session;
4869 this.bidiMap = {};
4870 this.currentRow = null;
4871 this.bidiUtil = bidiUtil;
4872 this.charWidths = [];
4873 this.EOL = "\xAC";
4874 this.showInvisibles = true;
4875 this.isRtlDir = false;
4876 this.line = "";
4877 this.wrapIndent = 0;
4878 this.isLastRow = false;
4879 this.EOF = "\xB6";
4880 this.seenBidi = false;
4881};
4882
4883(function() {
4884 this.isBidiRow = function(screenRow, docRow, splitIndex) {
4885 if (!this.seenBidi)
4886 return false;
4887 if (screenRow !== this.currentRow) {
4888 this.currentRow = screenRow;
4889 this.updateRowLine(docRow, splitIndex);
4890 this.updateBidiMap();
4891 }
4892 return this.bidiMap.bidiLevels;
4893 };
4894
4895 this.onChange = function(delta) {
4896 if (!this.seenBidi) {
4897 if (delta.action == "insert" && bidiRE.test(delta.lines.join("\n"))) {
4898 this.seenBidi = true;
4899 this.currentRow = null;
4900 }
4901 }
4902 else {
4903 this.currentRow = null;
4904 }
4905 };
4906
4907 this.getDocumentRow = function() {
4908 var docRow = 0;
4909 var rowCache = this.session.$screenRowCache;
4910 if (rowCache.length) {
4911 var index = this.session.$getRowCacheIndex(rowCache, this.currentRow);
4912 if (index >= 0)
4913 docRow = this.session.$docRowCache[index];
4914 }
4915
4916 return docRow;
4917 };
4918
4919 this.getSplitIndex = function() {
4920 var splitIndex = 0;
4921 var rowCache = this.session.$screenRowCache;
4922 if (rowCache.length) {
4923 var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow);
4924 while (this.currentRow - splitIndex > 0) {
4925 currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1);
4926 if (currentIndex !== prevIndex)
4927 break;
4928
4929 prevIndex = currentIndex;
4930 splitIndex++;
4931 }
4932 }
4933
4934 return splitIndex;
4935 };
4936
4937 this.updateRowLine = function(docRow, splitIndex) {
4938 if (docRow === undefined)
4939 docRow = this.getDocumentRow();
4940
4941 this.wrapIndent = 0;
4942 this.isLastRow = (docRow === this.session.getLength() - 1);
4943 this.line = this.session.getLine(docRow);
4944 if (this.session.$useWrapMode) {
4945 var splits = this.session.$wrapData[docRow];
4946 if (splits) {
4947 if (splitIndex === undefined)
4948 splitIndex = this.getSplitIndex();
4949
4950 if(splitIndex > 0 && splits.length) {
4951 this.wrapIndent = splits.indent;
4952 this.line = (splitIndex < splits.length) ?
4953 this.line.substring(splits[splitIndex - 1], splits[splits.length - 1]) :
4954 this.line.substring(splits[splits.length - 1]);
4955 } else {
4956 this.line = this.line.substring(0, splits[splitIndex]);
4957 }
4958 }
4959 }
4960 var session = this.session, shift = 0, size;
4961 this.line = this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g, function(ch, i){
4962 if (ch === '\t' || session.isFullWidth(ch.charCodeAt(0))) {
4963 size = (ch === '\t') ? session.getScreenTabSize(i + shift) : 2;
4964 shift += size - 1;
4965 return lang.stringRepeat(bidiUtil.DOT, size);
4966 }
4967 return ch;
4968 });
4969 };
4970
4971 this.updateBidiMap = function() {
4972 var textCharTypes = [], endOfLine = this.isLastRow ? this.EOF : this.EOL;
4973 var line = this.line + (this.showInvisibles ? endOfLine : bidiUtil.DOT);
4974 if (bidiUtil.hasBidiCharacters(line, textCharTypes)) {
4975 this.bidiMap = bidiUtil.doBidiReorder(line, textCharTypes, this.isRtlDir);
4976 } else {
4977 this.bidiMap = {};
4978 }
4979 };
4980 this.markAsDirty = function() {
4981 this.currentRow = null;
4982 };
4983 this.updateCharacterWidths = function(fontMetrics) {
4984 if (!this.seenBidi)
4985 return;
4986 if (this.characterWidth === fontMetrics.$characterSize.width)
4987 return;
4988
4989 var characterWidth = this.characterWidth = fontMetrics.$characterSize.width;
4990 var bidiCharWidth = fontMetrics.$measureCharWidth("\u05d4");
4991
4992 this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth;
4993 this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth;
4994 this.charWidths[bidiUtil.R_H] = useragent.isChrome ? bidiCharWidth : bidiCharWidth * 0.45;
4995 this.charWidths[bidiUtil.B] = 0;
4996
4997 this.currentRow = null;
4998 };
4999
5000 this.getShowInvisibles = function() {
5001 return this.showInvisibles;
5002 };
5003
5004 this.setShowInvisibles = function(showInvisibles) {
5005 this.showInvisibles = showInvisibles;
5006 this.currentRow = null;
5007 };
5008
5009 this.setEolChar = function(eolChar) {
5010 this.EOL = eolChar;
5011 };
5012
5013 this.setTextDir = function(isRtlDir) {
5014 this.isRtlDir = isRtlDir;
5015 };
5016 this.getPosLeft = function(col) {
5017 col -= this.wrapIndent;
5018 var visualIdx = bidiUtil.getVisualFromLogicalIdx(col > 0 ? col - 1 : 0, this.bidiMap),
5019 levels = this.bidiMap.bidiLevels, left = 0;
5020
5021 if (col === 0 && levels[visualIdx] % 2 !== 0)
5022 visualIdx++;
5023
5024 for (var i = 0; i < visualIdx; i++) {
5025 left += this.charWidths[levels[i]];
5026 }
5027
5028 if (col !== 0 && levels[visualIdx] % 2 === 0)
5029 left += this.charWidths[levels[visualIdx]];
5030
5031 if (this.wrapIndent)
5032 left += this.wrapIndent * this.charWidths[bidiUtil.L];
5033
5034 return left;
5035 };
5036 this.getSelections = function(startCol, endCol) {
5037 var map = this.bidiMap, levels = map.bidiLevels, level, offset = this.wrapIndent * this.charWidths[bidiUtil.L], selections = [],
5038 selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent,
5039 isSelected = false, isSelectedPrev = false, selectionStart = 0;
5040
5041 for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) {
5042 logIdx = map.logicalFromVisual[visIdx];
5043 level = levels[visIdx];
5044 isSelected = (logIdx >= selColMin) && (logIdx < selColMax);
5045 if (isSelected && !isSelectedPrev) {
5046 selectionStart = offset;
5047 } else if (!isSelected && isSelectedPrev) {
5048 selections.push({left: selectionStart, width: offset - selectionStart});
5049 }
5050 offset += this.charWidths[level];
5051 isSelectedPrev = isSelected;
5052 }
5053
5054 if (isSelected && (visIdx === levels.length)) {
5055 selections.push({left: selectionStart, width: offset - selectionStart});
5056 }
5057
5058 return selections;
5059 };
5060 this.offsetToCol = function(posX) {
5061 var logicalIdx = 0, posX = Math.max(posX, 0),
5062 offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels,
5063 charWidth = this.charWidths[levels[visualIdx]];
5064
5065 if (this.wrapIndent) {
5066 posX -= this.wrapIndent * this.charWidths[bidiUtil.L];
5067 }
5068
5069 while(posX > offset + charWidth/2) {
5070 offset += charWidth;
5071 if(visualIdx === levels.length - 1) {
5072 charWidth = 0;
5073 break;
5074 }
5075 charWidth = this.charWidths[levels[++visualIdx]];
5076 }
5077
5078 if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){
5079 if(posX < offset)
5080 visualIdx--;
5081 logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];
5082
5083 } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){
5084 logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx]
5085 : this.bidiMap.logicalFromVisual[visualIdx - 1]);
5086
5087 } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0))
5088 || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){
5089 logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx];
5090 } else {
5091 if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0)
5092 visualIdx--;
5093 logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];
5094 }
5095
5096 return (logicalIdx + this.wrapIndent);
5097 };
5098
5099}).call(BidiHandler.prototype);
5100
5101exports.BidiHandler = BidiHandler;
5102});
5103
5104ace.define("ace/range",["require","exports","module"], function(acequire, exports, module) {
5105var comparePoints = function(p1, p2) {
5106 return p1.row - p2.row || p1.column - p2.column;
5107};
5108var Range = function(startRow, startColumn, endRow, endColumn) {
5109 this.start = {
5110 row: startRow,
5111 column: startColumn
5112 };
5113
5114 this.end = {
5115 row: endRow,
5116 column: endColumn
5117 };
5118};
5119
5120(function() {
5121 this.isEqual = function(range) {
5122 return this.start.row === range.start.row &&
5123 this.end.row === range.end.row &&
5124 this.start.column === range.start.column &&
5125 this.end.column === range.end.column;
5126 };
5127 this.toString = function() {
5128 return ("Range: [" + this.start.row + "/" + this.start.column +
5129 "] -> [" + this.end.row + "/" + this.end.column + "]");
5130 };
5131
5132 this.contains = function(row, column) {
5133 return this.compare(row, column) == 0;
5134 };
5135 this.compareRange = function(range) {
5136 var cmp,
5137 end = range.end,
5138 start = range.start;
5139
5140 cmp = this.compare(end.row, end.column);
5141 if (cmp == 1) {
5142 cmp = this.compare(start.row, start.column);
5143 if (cmp == 1) {
5144 return 2;
5145 } else if (cmp == 0) {
5146 return 1;
5147 } else {
5148 return 0;
5149 }
5150 } else if (cmp == -1) {
5151 return -2;
5152 } else {
5153 cmp = this.compare(start.row, start.column);
5154 if (cmp == -1) {
5155 return -1;
5156 } else if (cmp == 1) {
5157 return 42;
5158 } else {
5159 return 0;
5160 }
5161 }
5162 };
5163 this.comparePoint = function(p) {
5164 return this.compare(p.row, p.column);
5165 };
5166 this.containsRange = function(range) {
5167 return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
5168 };
5169 this.intersects = function(range) {
5170 var cmp = this.compareRange(range);
5171 return (cmp == -1 || cmp == 0 || cmp == 1);
5172 };
5173 this.isEnd = function(row, column) {
5174 return this.end.row == row && this.end.column == column;
5175 };
5176 this.isStart = function(row, column) {
5177 return this.start.row == row && this.start.column == column;
5178 };
5179 this.setStart = function(row, column) {
5180 if (typeof row == "object") {
5181 this.start.column = row.column;
5182 this.start.row = row.row;
5183 } else {
5184 this.start.row = row;
5185 this.start.column = column;
5186 }
5187 };
5188 this.setEnd = function(row, column) {
5189 if (typeof row == "object") {
5190 this.end.column = row.column;
5191 this.end.row = row.row;
5192 } else {
5193 this.end.row = row;
5194 this.end.column = column;
5195 }
5196 };
5197 this.inside = function(row, column) {
5198 if (this.compare(row, column) == 0) {
5199 if (this.isEnd(row, column) || this.isStart(row, column)) {
5200 return false;
5201 } else {
5202 return true;
5203 }
5204 }
5205 return false;
5206 };
5207 this.insideStart = function(row, column) {
5208 if (this.compare(row, column) == 0) {
5209 if (this.isEnd(row, column)) {
5210 return false;
5211 } else {
5212 return true;
5213 }
5214 }
5215 return false;
5216 };
5217 this.insideEnd = function(row, column) {
5218 if (this.compare(row, column) == 0) {
5219 if (this.isStart(row, column)) {
5220 return false;
5221 } else {
5222 return true;
5223 }
5224 }
5225 return false;
5226 };
5227 this.compare = function(row, column) {
5228 if (!this.isMultiLine()) {
5229 if (row === this.start.row) {
5230 return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
5231 }
5232 }
5233
5234 if (row < this.start.row)
5235 return -1;
5236
5237 if (row > this.end.row)
5238 return 1;
5239
5240 if (this.start.row === row)
5241 return column >= this.start.column ? 0 : -1;
5242
5243 if (this.end.row === row)
5244 return column <= this.end.column ? 0 : 1;
5245
5246 return 0;
5247 };
5248 this.compareStart = function(row, column) {
5249 if (this.start.row == row && this.start.column == column) {
5250 return -1;
5251 } else {
5252 return this.compare(row, column);
5253 }
5254 };
5255 this.compareEnd = function(row, column) {
5256 if (this.end.row == row && this.end.column == column) {
5257 return 1;
5258 } else {
5259 return this.compare(row, column);
5260 }
5261 };
5262 this.compareInside = function(row, column) {
5263 if (this.end.row == row && this.end.column == column) {
5264 return 1;
5265 } else if (this.start.row == row && this.start.column == column) {
5266 return -1;
5267 } else {
5268 return this.compare(row, column);
5269 }
5270 };
5271 this.clipRows = function(firstRow, lastRow) {
5272 if (this.end.row > lastRow)
5273 var end = {row: lastRow + 1, column: 0};
5274 else if (this.end.row < firstRow)
5275 var end = {row: firstRow, column: 0};
5276
5277 if (this.start.row > lastRow)
5278 var start = {row: lastRow + 1, column: 0};
5279 else if (this.start.row < firstRow)
5280 var start = {row: firstRow, column: 0};
5281
5282 return Range.fromPoints(start || this.start, end || this.end);
5283 };
5284 this.extend = function(row, column) {
5285 var cmp = this.compare(row, column);
5286
5287 if (cmp == 0)
5288 return this;
5289 else if (cmp == -1)
5290 var start = {row: row, column: column};
5291 else
5292 var end = {row: row, column: column};
5293
5294 return Range.fromPoints(start || this.start, end || this.end);
5295 };
5296
5297 this.isEmpty = function() {
5298 return (this.start.row === this.end.row && this.start.column === this.end.column);
5299 };
5300 this.isMultiLine = function() {
5301 return (this.start.row !== this.end.row);
5302 };
5303 this.clone = function() {
5304 return Range.fromPoints(this.start, this.end);
5305 };
5306 this.collapseRows = function() {
5307 if (this.end.column == 0)
5308 return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);
5309 else
5310 return new Range(this.start.row, 0, this.end.row, 0);
5311 };
5312 this.toScreenRange = function(session) {
5313 var screenPosStart = session.documentToScreenPosition(this.start);
5314 var screenPosEnd = session.documentToScreenPosition(this.end);
5315
5316 return new Range(
5317 screenPosStart.row, screenPosStart.column,
5318 screenPosEnd.row, screenPosEnd.column
5319 );
5320 };
5321 this.moveBy = function(row, column) {
5322 this.start.row += row;
5323 this.start.column += column;
5324 this.end.row += row;
5325 this.end.column += column;
5326 };
5327
5328}).call(Range.prototype);
5329Range.fromPoints = function(start, end) {
5330 return new Range(start.row, start.column, end.row, end.column);
5331};
5332Range.comparePoints = comparePoints;
5333
5334Range.comparePoints = function(p1, p2) {
5335 return p1.row - p2.row || p1.column - p2.column;
5336};
5337
5338
5339exports.Range = Range;
5340});
5341
5342ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"], function(acequire, exports, module) {
5343
5344var oop = acequire("./lib/oop");
5345var lang = acequire("./lib/lang");
5346var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
5347var Range = acequire("./range").Range;
5348var Selection = function(session) {
5349 this.session = session;
5350 this.doc = session.getDocument();
5351
5352 this.clearSelection();
5353 this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
5354 this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
5355
5356 var self = this;
5357 this.lead.on("change", function(e) {
5358 self._emit("changeCursor");
5359 if (!self.$isEmpty)
5360 self._emit("changeSelection");
5361 if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)
5362 self.$desiredColumn = null;
5363 });
5364
5365 this.selectionAnchor.on("change", function() {
5366 if (!self.$isEmpty)
5367 self._emit("changeSelection");
5368 });
5369};
5370
5371(function() {
5372
5373 oop.implement(this, EventEmitter);
5374 this.isEmpty = function() {
5375 return (this.$isEmpty || (
5376 this.anchor.row == this.lead.row &&
5377 this.anchor.column == this.lead.column
5378 ));
5379 };
5380 this.isMultiLine = function() {
5381 if (this.isEmpty()) {
5382 return false;
5383 }
5384
5385 return this.getRange().isMultiLine();
5386 };
5387 this.getCursor = function() {
5388 return this.lead.getPosition();
5389 };
5390 this.setSelectionAnchor = function(row, column) {
5391 this.anchor.setPosition(row, column);
5392
5393 if (this.$isEmpty) {
5394 this.$isEmpty = false;
5395 this._emit("changeSelection");
5396 }
5397 };
5398 this.getSelectionAnchor = function() {
5399 if (this.$isEmpty)
5400 return this.getSelectionLead();
5401 else
5402 return this.anchor.getPosition();
5403 };
5404 this.getSelectionLead = function() {
5405 return this.lead.getPosition();
5406 };
5407 this.shiftSelection = function(columns) {
5408 if (this.$isEmpty) {
5409 this.moveCursorTo(this.lead.row, this.lead.column + columns);
5410 return;
5411 }
5412
5413 var anchor = this.getSelectionAnchor();
5414 var lead = this.getSelectionLead();
5415
5416 var isBackwards = this.isBackwards();
5417
5418 if (!isBackwards || anchor.column !== 0)
5419 this.setSelectionAnchor(anchor.row, anchor.column + columns);
5420
5421 if (isBackwards || lead.column !== 0) {
5422 this.$moveSelection(function() {
5423 this.moveCursorTo(lead.row, lead.column + columns);
5424 });
5425 }
5426 };
5427 this.isBackwards = function() {
5428 var anchor = this.anchor;
5429 var lead = this.lead;
5430 return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
5431 };
5432 this.getRange = function() {
5433 var anchor = this.anchor;
5434 var lead = this.lead;
5435
5436 if (this.isEmpty())
5437 return Range.fromPoints(lead, lead);
5438
5439 if (this.isBackwards()) {
5440 return Range.fromPoints(lead, anchor);
5441 }
5442 else {
5443 return Range.fromPoints(anchor, lead);
5444 }
5445 };
5446 this.clearSelection = function() {
5447 if (!this.$isEmpty) {
5448 this.$isEmpty = true;
5449 this._emit("changeSelection");
5450 }
5451 };
5452 this.selectAll = function() {
5453 var lastRow = this.doc.getLength() - 1;
5454 this.setSelectionAnchor(0, 0);
5455 this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);
5456 };
5457 this.setRange =
5458 this.setSelectionRange = function(range, reverse) {
5459 if (reverse) {
5460 this.setSelectionAnchor(range.end.row, range.end.column);
5461 this.selectTo(range.start.row, range.start.column);
5462 } else {
5463 this.setSelectionAnchor(range.start.row, range.start.column);
5464 this.selectTo(range.end.row, range.end.column);
5465 }
5466 if (this.getRange().isEmpty())
5467 this.$isEmpty = true;
5468 this.$desiredColumn = null;
5469 };
5470
5471 this.$moveSelection = function(mover) {
5472 var lead = this.lead;
5473 if (this.$isEmpty)
5474 this.setSelectionAnchor(lead.row, lead.column);
5475
5476 mover.call(this);
5477 };
5478 this.selectTo = function(row, column) {
5479 this.$moveSelection(function() {
5480 this.moveCursorTo(row, column);
5481 });
5482 };
5483 this.selectToPosition = function(pos) {
5484 this.$moveSelection(function() {
5485 this.moveCursorToPosition(pos);
5486 });
5487 };
5488 this.moveTo = function(row, column) {
5489 this.clearSelection();
5490 this.moveCursorTo(row, column);
5491 };
5492 this.moveToPosition = function(pos) {
5493 this.clearSelection();
5494 this.moveCursorToPosition(pos);
5495 };
5496 this.selectUp = function() {
5497 this.$moveSelection(this.moveCursorUp);
5498 };
5499 this.selectDown = function() {
5500 this.$moveSelection(this.moveCursorDown);
5501 };
5502 this.selectRight = function() {
5503 this.$moveSelection(this.moveCursorRight);
5504 };
5505 this.selectLeft = function() {
5506 this.$moveSelection(this.moveCursorLeft);
5507 };
5508 this.selectLineStart = function() {
5509 this.$moveSelection(this.moveCursorLineStart);
5510 };
5511 this.selectLineEnd = function() {
5512 this.$moveSelection(this.moveCursorLineEnd);
5513 };
5514 this.selectFileEnd = function() {
5515 this.$moveSelection(this.moveCursorFileEnd);
5516 };
5517 this.selectFileStart = function() {
5518 this.$moveSelection(this.moveCursorFileStart);
5519 };
5520 this.selectWordRight = function() {
5521 this.$moveSelection(this.moveCursorWordRight);
5522 };
5523 this.selectWordLeft = function() {
5524 this.$moveSelection(this.moveCursorWordLeft);
5525 };
5526 this.getWordRange = function(row, column) {
5527 if (typeof column == "undefined") {
5528 var cursor = row || this.lead;
5529 row = cursor.row;
5530 column = cursor.column;
5531 }
5532 return this.session.getWordRange(row, column);
5533 };
5534 this.selectWord = function() {
5535 this.setSelectionRange(this.getWordRange());
5536 };
5537 this.selectAWord = function() {
5538 var cursor = this.getCursor();
5539 var range = this.session.getAWordRange(cursor.row, cursor.column);
5540 this.setSelectionRange(range);
5541 };
5542
5543 this.getLineRange = function(row, excludeLastChar) {
5544 var rowStart = typeof row == "number" ? row : this.lead.row;
5545 var rowEnd;
5546
5547 var foldLine = this.session.getFoldLine(rowStart);
5548 if (foldLine) {
5549 rowStart = foldLine.start.row;
5550 rowEnd = foldLine.end.row;
5551 } else {
5552 rowEnd = rowStart;
5553 }
5554 if (excludeLastChar === true)
5555 return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
5556 else
5557 return new Range(rowStart, 0, rowEnd + 1, 0);
5558 };
5559 this.selectLine = function() {
5560 this.setSelectionRange(this.getLineRange());
5561 };
5562 this.moveCursorUp = function() {
5563 this.moveCursorBy(-1, 0);
5564 };
5565 this.moveCursorDown = function() {
5566 this.moveCursorBy(1, 0);
5567 };
5568 this.wouldMoveIntoSoftTab = function(cursor, tabSize, direction) {
5569 var start = cursor.column;
5570 var end = cursor.column + tabSize;
5571
5572 if (direction < 0) {
5573 start = cursor.column - tabSize;
5574 end = cursor.column;
5575 }
5576 return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(" ").length-1 == tabSize;
5577 };
5578 this.moveCursorLeft = function() {
5579 var cursor = this.lead.getPosition(),
5580 fold;
5581
5582 if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
5583 this.moveCursorTo(fold.start.row, fold.start.column);
5584 } else if (cursor.column === 0) {
5585 if (cursor.row > 0) {
5586 this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
5587 }
5588 }
5589 else {
5590 var tabSize = this.session.getTabSize();
5591 if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) {
5592 this.moveCursorBy(0, -tabSize);
5593 } else {
5594 this.moveCursorBy(0, -1);
5595 }
5596 }
5597 };
5598 this.moveCursorRight = function() {
5599 var cursor = this.lead.getPosition(),
5600 fold;
5601 if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
5602 this.moveCursorTo(fold.end.row, fold.end.column);
5603 }
5604 else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
5605 if (this.lead.row < this.doc.getLength() - 1) {
5606 this.moveCursorTo(this.lead.row + 1, 0);
5607 }
5608 }
5609 else {
5610 var tabSize = this.session.getTabSize();
5611 var cursor = this.lead;
5612 if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) {
5613 this.moveCursorBy(0, tabSize);
5614 } else {
5615 this.moveCursorBy(0, 1);
5616 }
5617 }
5618 };
5619 this.moveCursorLineStart = function() {
5620 var row = this.lead.row;
5621 var column = this.lead.column;
5622 var screenRow = this.session.documentToScreenRow(row, column);
5623 var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);
5624 var beforeCursor = this.session.getDisplayLine(
5625 row, null, firstColumnPosition.row,
5626 firstColumnPosition.column
5627 );
5628
5629 var leadingSpace = beforeCursor.match(/^\s*/);
5630 if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)
5631 firstColumnPosition.column += leadingSpace[0].length;
5632 this.moveCursorToPosition(firstColumnPosition);
5633 };
5634 this.moveCursorLineEnd = function() {
5635 var lead = this.lead;
5636 var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
5637 if (this.lead.column == lineEnd.column) {
5638 var line = this.session.getLine(lineEnd.row);
5639 if (lineEnd.column == line.length) {
5640 var textEnd = line.search(/\s+$/);
5641 if (textEnd > 0)
5642 lineEnd.column = textEnd;
5643 }
5644 }
5645
5646 this.moveCursorTo(lineEnd.row, lineEnd.column);
5647 };
5648 this.moveCursorFileEnd = function() {
5649 var row = this.doc.getLength() - 1;
5650 var column = this.doc.getLine(row).length;
5651 this.moveCursorTo(row, column);
5652 };
5653 this.moveCursorFileStart = function() {
5654 this.moveCursorTo(0, 0);
5655 };
5656 this.moveCursorLongWordRight = function() {
5657 var row = this.lead.row;
5658 var column = this.lead.column;
5659 var line = this.doc.getLine(row);
5660 var rightOfCursor = line.substring(column);
5661 this.session.nonTokenRe.lastIndex = 0;
5662 this.session.tokenRe.lastIndex = 0;
5663 var fold = this.session.getFoldAt(row, column, 1);
5664 if (fold) {
5665 this.moveCursorTo(fold.end.row, fold.end.column);
5666 return;
5667 }
5668 if (this.session.nonTokenRe.exec(rightOfCursor)) {
5669 column += this.session.nonTokenRe.lastIndex;
5670 this.session.nonTokenRe.lastIndex = 0;
5671 rightOfCursor = line.substring(column);
5672 }
5673 if (column >= line.length) {
5674 this.moveCursorTo(row, line.length);
5675 this.moveCursorRight();
5676 if (row < this.doc.getLength() - 1)
5677 this.moveCursorWordRight();
5678 return;
5679 }
5680 if (this.session.tokenRe.exec(rightOfCursor)) {
5681 column += this.session.tokenRe.lastIndex;
5682 this.session.tokenRe.lastIndex = 0;
5683 }
5684
5685 this.moveCursorTo(row, column);
5686 };
5687 this.moveCursorLongWordLeft = function() {
5688 var row = this.lead.row;
5689 var column = this.lead.column;
5690 var fold;
5691 if (fold = this.session.getFoldAt(row, column, -1)) {
5692 this.moveCursorTo(fold.start.row, fold.start.column);
5693 return;
5694 }
5695
5696 var str = this.session.getFoldStringAt(row, column, -1);
5697 if (str == null) {
5698 str = this.doc.getLine(row).substring(0, column);
5699 }
5700
5701 var leftOfCursor = lang.stringReverse(str);
5702 this.session.nonTokenRe.lastIndex = 0;
5703 this.session.tokenRe.lastIndex = 0;
5704 if (this.session.nonTokenRe.exec(leftOfCursor)) {
5705 column -= this.session.nonTokenRe.lastIndex;
5706 leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
5707 this.session.nonTokenRe.lastIndex = 0;
5708 }
5709 if (column <= 0) {
5710 this.moveCursorTo(row, 0);
5711 this.moveCursorLeft();
5712 if (row > 0)
5713 this.moveCursorWordLeft();
5714 return;
5715 }
5716 if (this.session.tokenRe.exec(leftOfCursor)) {
5717 column -= this.session.tokenRe.lastIndex;
5718 this.session.tokenRe.lastIndex = 0;
5719 }
5720
5721 this.moveCursorTo(row, column);
5722 };
5723
5724 this.$shortWordEndIndex = function(rightOfCursor) {
5725 var index = 0, ch;
5726 var whitespaceRe = /\s/;
5727 var tokenRe = this.session.tokenRe;
5728
5729 tokenRe.lastIndex = 0;
5730 if (this.session.tokenRe.exec(rightOfCursor)) {
5731 index = this.session.tokenRe.lastIndex;
5732 } else {
5733 while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
5734 index ++;
5735
5736 if (index < 1) {
5737 tokenRe.lastIndex = 0;
5738 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
5739 tokenRe.lastIndex = 0;
5740 index ++;
5741 if (whitespaceRe.test(ch)) {
5742 if (index > 2) {
5743 index--;
5744 break;
5745 } else {
5746 while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
5747 index ++;
5748 if (index > 2)
5749 break;
5750 }
5751 }
5752 }
5753 }
5754 }
5755 tokenRe.lastIndex = 0;
5756
5757 return index;
5758 };
5759
5760 this.moveCursorShortWordRight = function() {
5761 var row = this.lead.row;
5762 var column = this.lead.column;
5763 var line = this.doc.getLine(row);
5764 var rightOfCursor = line.substring(column);
5765
5766 var fold = this.session.getFoldAt(row, column, 1);
5767 if (fold)
5768 return this.moveCursorTo(fold.end.row, fold.end.column);
5769
5770 if (column == line.length) {
5771 var l = this.doc.getLength();
5772 do {
5773 row++;
5774 rightOfCursor = this.doc.getLine(row);
5775 } while (row < l && /^\s*$/.test(rightOfCursor));
5776
5777 if (!/^\s+/.test(rightOfCursor))
5778 rightOfCursor = "";
5779 column = 0;
5780 }
5781
5782 var index = this.$shortWordEndIndex(rightOfCursor);
5783
5784 this.moveCursorTo(row, column + index);
5785 };
5786
5787 this.moveCursorShortWordLeft = function() {
5788 var row = this.lead.row;
5789 var column = this.lead.column;
5790
5791 var fold;
5792 if (fold = this.session.getFoldAt(row, column, -1))
5793 return this.moveCursorTo(fold.start.row, fold.start.column);
5794
5795 var line = this.session.getLine(row).substring(0, column);
5796 if (column === 0) {
5797 do {
5798 row--;
5799 line = this.doc.getLine(row);
5800 } while (row > 0 && /^\s*$/.test(line));
5801
5802 column = line.length;
5803 if (!/\s+$/.test(line))
5804 line = "";
5805 }
5806
5807 var leftOfCursor = lang.stringReverse(line);
5808 var index = this.$shortWordEndIndex(leftOfCursor);
5809
5810 return this.moveCursorTo(row, column - index);
5811 };
5812
5813 this.moveCursorWordRight = function() {
5814 if (this.session.$selectLongWords)
5815 this.moveCursorLongWordRight();
5816 else
5817 this.moveCursorShortWordRight();
5818 };
5819
5820 this.moveCursorWordLeft = function() {
5821 if (this.session.$selectLongWords)
5822 this.moveCursorLongWordLeft();
5823 else
5824 this.moveCursorShortWordLeft();
5825 };
5826 this.moveCursorBy = function(rows, chars) {
5827 var screenPos = this.session.documentToScreenPosition(
5828 this.lead.row,
5829 this.lead.column
5830 );
5831
5832 var offsetX;
5833
5834 if (chars === 0) {
5835 if (rows !== 0) {
5836 if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) {
5837 offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column);
5838 screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]);
5839 } else {
5840 offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0];
5841 }
5842 }
5843
5844 if (this.$desiredColumn)
5845 screenPos.column = this.$desiredColumn;
5846 else
5847 this.$desiredColumn = screenPos.column;
5848 }
5849
5850 var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);
5851
5852 if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {
5853 if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) {
5854 if (docPos.row > 0 || rows > 0)
5855 docPos.row++;
5856 }
5857 }
5858 this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
5859 };
5860 this.moveCursorToPosition = function(position) {
5861 this.moveCursorTo(position.row, position.column);
5862 };
5863 this.moveCursorTo = function(row, column, keepDesiredColumn) {
5864 var fold = this.session.getFoldAt(row, column, 1);
5865 if (fold) {
5866 row = fold.start.row;
5867 column = fold.start.column;
5868 }
5869
5870 this.$keepDesiredColumnOnChange = true;
5871 var line = this.session.getLine(row);
5872 if (/[\uDC00-\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) {
5873 if (this.lead.row == row && this.lead.column == column + 1)
5874 column = column - 1;
5875 else
5876 column = column + 1;
5877 }
5878 this.lead.setPosition(row, column);
5879 this.$keepDesiredColumnOnChange = false;
5880
5881 if (!keepDesiredColumn)
5882 this.$desiredColumn = null;
5883 };
5884 this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
5885 var pos = this.session.screenToDocumentPosition(row, column);
5886 this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
5887 };
5888 this.detach = function() {
5889 this.lead.detach();
5890 this.anchor.detach();
5891 this.session = this.doc = null;
5892 };
5893
5894 this.fromOrientedRange = function(range) {
5895 this.setSelectionRange(range, range.cursor == range.start);
5896 this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
5897 };
5898
5899 this.toOrientedRange = function(range) {
5900 var r = this.getRange();
5901 if (range) {
5902 range.start.column = r.start.column;
5903 range.start.row = r.start.row;
5904 range.end.column = r.end.column;
5905 range.end.row = r.end.row;
5906 } else {
5907 range = r;
5908 }
5909
5910 range.cursor = this.isBackwards() ? range.start : range.end;
5911 range.desiredColumn = this.$desiredColumn;
5912 return range;
5913 };
5914 this.getRangeOfMovements = function(func) {
5915 var start = this.getCursor();
5916 try {
5917 func(this);
5918 var end = this.getCursor();
5919 return Range.fromPoints(start,end);
5920 } catch(e) {
5921 return Range.fromPoints(start,start);
5922 } finally {
5923 this.moveCursorToPosition(start);
5924 }
5925 };
5926
5927 this.toJSON = function() {
5928 if (this.rangeCount) {
5929 var data = this.ranges.map(function(r) {
5930 var r1 = r.clone();
5931 r1.isBackwards = r.cursor == r.start;
5932 return r1;
5933 });
5934 } else {
5935 var data = this.getRange();
5936 data.isBackwards = this.isBackwards();
5937 }
5938 return data;
5939 };
5940
5941 this.fromJSON = function(data) {
5942 if (data.start == undefined) {
5943 if (this.rangeList) {
5944 this.toSingleRange(data[0]);
5945 for (var i = data.length; i--; ) {
5946 var r = Range.fromPoints(data[i].start, data[i].end);
5947 if (data[i].isBackwards)
5948 r.cursor = r.start;
5949 this.addRange(r, true);
5950 }
5951 return;
5952 } else
5953 data = data[0];
5954 }
5955 if (this.rangeList)
5956 this.toSingleRange(data);
5957 this.setSelectionRange(data, data.isBackwards);
5958 };
5959
5960 this.isEqual = function(data) {
5961 if ((data.length || this.rangeCount) && data.length != this.rangeCount)
5962 return false;
5963 if (!data.length || !this.ranges)
5964 return this.getRange().isEqual(data);
5965
5966 for (var i = this.ranges.length; i--; ) {
5967 if (!this.ranges[i].isEqual(data[i]))
5968 return false;
5969 }
5970 return true;
5971 };
5972
5973}).call(Selection.prototype);
5974
5975exports.Selection = Selection;
5976});
5977
5978ace.define("ace/tokenizer",["require","exports","module","ace/config"], function(acequire, exports, module) {
5979
5980var config = acequire("./config");
5981var MAX_TOKEN_COUNT = 2000;
5982var Tokenizer = function(rules) {
5983 this.states = rules;
5984
5985 this.regExps = {};
5986 this.matchMappings = {};
5987 for (var key in this.states) {
5988 var state = this.states[key];
5989 var ruleRegExps = [];
5990 var matchTotal = 0;
5991 var mapping = this.matchMappings[key] = {defaultToken: "text"};
5992 var flag = "g";
5993
5994 var splitterRurles = [];
5995 for (var i = 0; i < state.length; i++) {
5996 var rule = state[i];
5997 if (rule.defaultToken)
5998 mapping.defaultToken = rule.defaultToken;
5999 if (rule.caseInsensitive)
6000 flag = "gi";
6001 if (rule.regex == null)
6002 continue;
6003
6004 if (rule.regex instanceof RegExp)
6005 rule.regex = rule.regex.toString().slice(1, -1);
6006 var adjustedregex = rule.regex;
6007 var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
6008 if (Array.isArray(rule.token)) {
6009 if (rule.token.length == 1 || matchcount == 1) {
6010 rule.token = rule.token[0];
6011 } else if (matchcount - 1 != rule.token.length) {
6012 this.reportError("number of classes and regexp groups doesn't match", {
6013 rule: rule,
6014 groupCount: matchcount - 1
6015 });
6016 rule.token = rule.token[0];
6017 } else {
6018 rule.tokenArray = rule.token;
6019 rule.token = null;
6020 rule.onMatch = this.$arrayTokens;
6021 }
6022 } else if (typeof rule.token == "function" && !rule.onMatch) {
6023 if (matchcount > 1)
6024 rule.onMatch = this.$applyToken;
6025 else
6026 rule.onMatch = rule.token;
6027 }
6028
6029 if (matchcount > 1) {
6030 if (/\\\d/.test(rule.regex)) {
6031 adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) {
6032 return "\\" + (parseInt(digit, 10) + matchTotal + 1);
6033 });
6034 } else {
6035 matchcount = 1;
6036 adjustedregex = this.removeCapturingGroups(rule.regex);
6037 }
6038 if (!rule.splitRegex && typeof rule.token != "string")
6039 splitterRurles.push(rule); // flag will be known only at the very end
6040 }
6041
6042 mapping[matchTotal] = i;
6043 matchTotal += matchcount;
6044
6045 ruleRegExps.push(adjustedregex);
6046 if (!rule.onMatch)
6047 rule.onMatch = null;
6048 }
6049
6050 if (!ruleRegExps.length) {
6051 mapping[0] = 0;
6052 ruleRegExps.push("$");
6053 }
6054
6055 splitterRurles.forEach(function(rule) {
6056 rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
6057 }, this);
6058
6059 this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
6060 }
6061};
6062
6063(function() {
6064 this.$setMaxTokenCount = function(m) {
6065 MAX_TOKEN_COUNT = m | 0;
6066 };
6067
6068 this.$applyToken = function(str) {
6069 var values = this.splitRegex.exec(str).slice(1);
6070 var types = this.token.apply(this, values);
6071 if (typeof types === "string")
6072 return [{type: types, value: str}];
6073
6074 var tokens = [];
6075 for (var i = 0, l = types.length; i < l; i++) {
6076 if (values[i])
6077 tokens[tokens.length] = {
6078 type: types[i],
6079 value: values[i]
6080 };
6081 }
6082 return tokens;
6083 };
6084
6085 this.$arrayTokens = function(str) {
6086 if (!str)
6087 return [];
6088 var values = this.splitRegex.exec(str);
6089 if (!values)
6090 return "text";
6091 var tokens = [];
6092 var types = this.tokenArray;
6093 for (var i = 0, l = types.length; i < l; i++) {
6094 if (values[i + 1])
6095 tokens[tokens.length] = {
6096 type: types[i],
6097 value: values[i + 1]
6098 };
6099 }
6100 return tokens;
6101 };
6102
6103 this.removeCapturingGroups = function(src) {
6104 var r = src.replace(
6105 /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
6106 function(x, y) {return y ? "(?:" : x;}
6107 );
6108 return r;
6109 };
6110
6111 this.createSplitterRegexp = function(src, flag) {
6112 if (src.indexOf("(?=") != -1) {
6113 var stack = 0;
6114 var inChClass = false;
6115 var lastCapture = {};
6116 src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function(
6117 m, esc, parenOpen, parenClose, square, index
6118 ) {
6119 if (inChClass) {
6120 inChClass = square != "]";
6121 } else if (square) {
6122 inChClass = true;
6123 } else if (parenClose) {
6124 if (stack == lastCapture.stack) {
6125 lastCapture.end = index+1;
6126 lastCapture.stack = -1;
6127 }
6128 stack--;
6129 } else if (parenOpen) {
6130 stack++;
6131 if (parenOpen.length != 1) {
6132 lastCapture.stack = stack;
6133 lastCapture.start = index;
6134 }
6135 }
6136 return m;
6137 });
6138
6139 if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
6140 src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
6141 }
6142 if (src.charAt(0) != "^") src = "^" + src;
6143 if (src.charAt(src.length - 1) != "$") src += "$";
6144
6145 return new RegExp(src, (flag||"").replace("g", ""));
6146 };
6147 this.getLineTokens = function(line, startState) {
6148 if (startState && typeof startState != "string") {
6149 var stack = startState.slice(0);
6150 startState = stack[0];
6151 if (startState === "#tmp") {
6152 stack.shift();
6153 startState = stack.shift();
6154 }
6155 } else
6156 var stack = [];
6157
6158 var currentState = startState || "start";
6159 var state = this.states[currentState];
6160 if (!state) {
6161 currentState = "start";
6162 state = this.states[currentState];
6163 }
6164 var mapping = this.matchMappings[currentState];
6165 var re = this.regExps[currentState];
6166 re.lastIndex = 0;
6167
6168 var match, tokens = [];
6169 var lastIndex = 0;
6170 var matchAttempts = 0;
6171
6172 var token = {type: null, value: ""};
6173
6174 while (match = re.exec(line)) {
6175 var type = mapping.defaultToken;
6176 var rule = null;
6177 var value = match[0];
6178 var index = re.lastIndex;
6179
6180 if (index - value.length > lastIndex) {
6181 var skipped = line.substring(lastIndex, index - value.length);
6182 if (token.type == type) {
6183 token.value += skipped;
6184 } else {
6185 if (token.type)
6186 tokens.push(token);
6187 token = {type: type, value: skipped};
6188 }
6189 }
6190
6191 for (var i = 0; i < match.length-2; i++) {
6192 if (match[i + 1] === undefined)
6193 continue;
6194
6195 rule = state[mapping[i]];
6196
6197 if (rule.onMatch)
6198 type = rule.onMatch(value, currentState, stack, line);
6199 else
6200 type = rule.token;
6201
6202 if (rule.next) {
6203 if (typeof rule.next == "string") {
6204 currentState = rule.next;
6205 } else {
6206 currentState = rule.next(currentState, stack);
6207 }
6208
6209 state = this.states[currentState];
6210 if (!state) {
6211 this.reportError("state doesn't exist", currentState);
6212 currentState = "start";
6213 state = this.states[currentState];
6214 }
6215 mapping = this.matchMappings[currentState];
6216 lastIndex = index;
6217 re = this.regExps[currentState];
6218 re.lastIndex = index;
6219 }
6220 if (rule.consumeLineEnd)
6221 lastIndex = index;
6222 break;
6223 }
6224
6225 if (value) {
6226 if (typeof type === "string") {
6227 if ((!rule || rule.merge !== false) && token.type === type) {
6228 token.value += value;
6229 } else {
6230 if (token.type)
6231 tokens.push(token);
6232 token = {type: type, value: value};
6233 }
6234 } else if (type) {
6235 if (token.type)
6236 tokens.push(token);
6237 token = {type: null, value: ""};
6238 for (var i = 0; i < type.length; i++)
6239 tokens.push(type[i]);
6240 }
6241 }
6242
6243 if (lastIndex == line.length)
6244 break;
6245
6246 lastIndex = index;
6247
6248 if (matchAttempts++ > MAX_TOKEN_COUNT) {
6249 if (matchAttempts > 2 * line.length) {
6250 this.reportError("infinite loop with in ace tokenizer", {
6251 startState: startState,
6252 line: line
6253 });
6254 }
6255 while (lastIndex < line.length) {
6256 if (token.type)
6257 tokens.push(token);
6258 token = {
6259 value: line.substring(lastIndex, lastIndex += 2000),
6260 type: "overflow"
6261 };
6262 }
6263 currentState = "start";
6264 stack = [];
6265 break;
6266 }
6267 }
6268
6269 if (token.type)
6270 tokens.push(token);
6271
6272 if (stack.length > 1) {
6273 if (stack[0] !== currentState)
6274 stack.unshift("#tmp", currentState);
6275 }
6276 return {
6277 tokens : tokens,
6278 state : stack.length ? stack : currentState
6279 };
6280 };
6281
6282 this.reportError = config.reportError;
6283
6284}).call(Tokenizer.prototype);
6285
6286exports.Tokenizer = Tokenizer;
6287});
6288
6289ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"], function(acequire, exports, module) {
6290
6291var lang = acequire("../lib/lang");
6292
6293var TextHighlightRules = function() {
6294
6295 this.$rules = {
6296 "start" : [{
6297 token : "empty_line",
6298 regex : '^$'
6299 }, {
6300 defaultToken : "text"
6301 }]
6302 };
6303};
6304
6305(function() {
6306
6307 this.addRules = function(rules, prefix) {
6308 if (!prefix) {
6309 for (var key in rules)
6310 this.$rules[key] = rules[key];
6311 return;
6312 }
6313 for (var key in rules) {
6314 var state = rules[key];
6315 for (var i = 0; i < state.length; i++) {
6316 var rule = state[i];
6317 if (rule.next || rule.onMatch) {
6318 if (typeof rule.next == "string") {
6319 if (rule.next.indexOf(prefix) !== 0)
6320 rule.next = prefix + rule.next;
6321 }
6322 if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)
6323 rule.nextState = prefix + rule.nextState;
6324 }
6325 }
6326 this.$rules[prefix + key] = state;
6327 }
6328 };
6329
6330 this.getRules = function() {
6331 return this.$rules;
6332 };
6333
6334 this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
6335 var embedRules = typeof HighlightRules == "function"
6336 ? new HighlightRules().getRules()
6337 : HighlightRules;
6338 if (states) {
6339 for (var i = 0; i < states.length; i++)
6340 states[i] = prefix + states[i];
6341 } else {
6342 states = [];
6343 for (var key in embedRules)
6344 states.push(prefix + key);
6345 }
6346
6347 this.addRules(embedRules, prefix);
6348
6349 if (escapeRules) {
6350 var addRules = Array.prototype[append ? "push" : "unshift"];
6351 for (var i = 0; i < states.length; i++)
6352 addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
6353 }
6354
6355 if (!this.$embeds)
6356 this.$embeds = [];
6357 this.$embeds.push(prefix);
6358 };
6359
6360 this.getEmbeds = function() {
6361 return this.$embeds;
6362 };
6363
6364 var pushState = function(currentState, stack) {
6365 if (currentState != "start" || stack.length)
6366 stack.unshift(this.nextState, currentState);
6367 return this.nextState;
6368 };
6369 var popState = function(currentState, stack) {
6370 stack.shift();
6371 return stack.shift() || "start";
6372 };
6373
6374 this.normalizeRules = function() {
6375 var id = 0;
6376 var rules = this.$rules;
6377 function processState(key) {
6378 var state = rules[key];
6379 state.processed = true;
6380 for (var i = 0; i < state.length; i++) {
6381 var rule = state[i];
6382 var toInsert = null;
6383 if (Array.isArray(rule)) {
6384 toInsert = rule;
6385 rule = {};
6386 }
6387 if (!rule.regex && rule.start) {
6388 rule.regex = rule.start;
6389 if (!rule.next)
6390 rule.next = [];
6391 rule.next.push({
6392 defaultToken: rule.token
6393 }, {
6394 token: rule.token + ".end",
6395 regex: rule.end || rule.start,
6396 next: "pop"
6397 });
6398 rule.token = rule.token + ".start";
6399 rule.push = true;
6400 }
6401 var next = rule.next || rule.push;
6402 if (next && Array.isArray(next)) {
6403 var stateName = rule.stateName;
6404 if (!stateName) {
6405 stateName = rule.token;
6406 if (typeof stateName != "string")
6407 stateName = stateName[0] || "";
6408 if (rules[stateName])
6409 stateName += id++;
6410 }
6411 rules[stateName] = next;
6412 rule.next = stateName;
6413 processState(stateName);
6414 } else if (next == "pop") {
6415 rule.next = popState;
6416 }
6417
6418 if (rule.push) {
6419 rule.nextState = rule.next || rule.push;
6420 rule.next = pushState;
6421 delete rule.push;
6422 }
6423
6424 if (rule.rules) {
6425 for (var r in rule.rules) {
6426 if (rules[r]) {
6427 if (rules[r].push)
6428 rules[r].push.apply(rules[r], rule.rules[r]);
6429 } else {
6430 rules[r] = rule.rules[r];
6431 }
6432 }
6433 }
6434 var includeName = typeof rule == "string" ? rule : rule.include;
6435 if (includeName) {
6436 if (Array.isArray(includeName))
6437 toInsert = includeName.map(function(x) { return rules[x]; });
6438 else
6439 toInsert = rules[includeName];
6440 }
6441
6442 if (toInsert) {
6443 var args = [i, 1].concat(toInsert);
6444 if (rule.noEscape)
6445 args = args.filter(function(x) {return !x.next;});
6446 state.splice.apply(state, args);
6447 i--;
6448 }
6449
6450 if (rule.keywordMap) {
6451 rule.token = this.createKeywordMapper(
6452 rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive
6453 );
6454 delete rule.defaultToken;
6455 }
6456 }
6457 }
6458 Object.keys(rules).forEach(processState, this);
6459 };
6460
6461 this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
6462 var keywords = Object.create(null);
6463 Object.keys(map).forEach(function(className) {
6464 var a = map[className];
6465 if (ignoreCase)
6466 a = a.toLowerCase();
6467 var list = a.split(splitChar || "|");
6468 for (var i = list.length; i--; )
6469 keywords[list[i]] = className;
6470 });
6471 if (Object.getPrototypeOf(keywords)) {
6472 keywords.__proto__ = null;
6473 }
6474 this.$keywordList = Object.keys(keywords);
6475 map = null;
6476 return ignoreCase
6477 ? function(value) {return keywords[value.toLowerCase()] || defaultToken; }
6478 : function(value) {return keywords[value] || defaultToken; };
6479 };
6480
6481 this.getKeywords = function() {
6482 return this.$keywords;
6483 };
6484
6485}).call(TextHighlightRules.prototype);
6486
6487exports.TextHighlightRules = TextHighlightRules;
6488});
6489
6490ace.define("ace/mode/behaviour",["require","exports","module"], function(acequire, exports, module) {
6491
6492var Behaviour = function() {
6493 this.$behaviours = {};
6494};
6495
6496(function () {
6497
6498 this.add = function (name, action, callback) {
6499 switch (undefined) {
6500 case this.$behaviours:
6501 this.$behaviours = {};
6502 case this.$behaviours[name]:
6503 this.$behaviours[name] = {};
6504 }
6505 this.$behaviours[name][action] = callback;
6506 };
6507
6508 this.addBehaviours = function (behaviours) {
6509 for (var key in behaviours) {
6510 for (var action in behaviours[key]) {
6511 this.add(key, action, behaviours[key][action]);
6512 }
6513 }
6514 };
6515
6516 this.remove = function (name) {
6517 if (this.$behaviours && this.$behaviours[name]) {
6518 delete this.$behaviours[name];
6519 }
6520 };
6521
6522 this.inherit = function (mode, filter) {
6523 if (typeof mode === "function") {
6524 var behaviours = new mode().getBehaviours(filter);
6525 } else {
6526 var behaviours = mode.getBehaviours(filter);
6527 }
6528 this.addBehaviours(behaviours);
6529 };
6530
6531 this.getBehaviours = function (filter) {
6532 if (!filter) {
6533 return this.$behaviours;
6534 } else {
6535 var ret = {};
6536 for (var i = 0; i < filter.length; i++) {
6537 if (this.$behaviours[filter[i]]) {
6538 ret[filter[i]] = this.$behaviours[filter[i]];
6539 }
6540 }
6541 return ret;
6542 }
6543 };
6544
6545}).call(Behaviour.prototype);
6546
6547exports.Behaviour = Behaviour;
6548});
6549
6550ace.define("ace/token_iterator",["require","exports","module","ace/range"], function(acequire, exports, module) {
6551
6552var Range = acequire("./range").Range;
6553var TokenIterator = function(session, initialRow, initialColumn) {
6554 this.$session = session;
6555 this.$row = initialRow;
6556 this.$rowTokens = session.getTokens(initialRow);
6557
6558 var token = session.getTokenAt(initialRow, initialColumn);
6559 this.$tokenIndex = token ? token.index : -1;
6560};
6561
6562(function() {
6563 this.stepBackward = function() {
6564 this.$tokenIndex -= 1;
6565
6566 while (this.$tokenIndex < 0) {
6567 this.$row -= 1;
6568 if (this.$row < 0) {
6569 this.$row = 0;
6570 return null;
6571 }
6572
6573 this.$rowTokens = this.$session.getTokens(this.$row);
6574 this.$tokenIndex = this.$rowTokens.length - 1;
6575 }
6576
6577 return this.$rowTokens[this.$tokenIndex];
6578 };
6579 this.stepForward = function() {
6580 this.$tokenIndex += 1;
6581 var rowCount;
6582 while (this.$tokenIndex >= this.$rowTokens.length) {
6583 this.$row += 1;
6584 if (!rowCount)
6585 rowCount = this.$session.getLength();
6586 if (this.$row >= rowCount) {
6587 this.$row = rowCount - 1;
6588 return null;
6589 }
6590
6591 this.$rowTokens = this.$session.getTokens(this.$row);
6592 this.$tokenIndex = 0;
6593 }
6594
6595 return this.$rowTokens[this.$tokenIndex];
6596 };
6597 this.getCurrentToken = function () {
6598 return this.$rowTokens[this.$tokenIndex];
6599 };
6600 this.getCurrentTokenRow = function () {
6601 return this.$row;
6602 };
6603 this.getCurrentTokenColumn = function() {
6604 var rowTokens = this.$rowTokens;
6605 var tokenIndex = this.$tokenIndex;
6606 var column = rowTokens[tokenIndex].start;
6607 if (column !== undefined)
6608 return column;
6609
6610 column = 0;
6611 while (tokenIndex > 0) {
6612 tokenIndex -= 1;
6613 column += rowTokens[tokenIndex].value.length;
6614 }
6615
6616 return column;
6617 };
6618 this.getCurrentTokenPosition = function() {
6619 return {row: this.$row, column: this.getCurrentTokenColumn()};
6620 };
6621 this.getCurrentTokenRange = function() {
6622 var token = this.$rowTokens[this.$tokenIndex];
6623 var column = this.getCurrentTokenColumn();
6624 return new Range(this.$row, column, this.$row, column + token.value.length);
6625 };
6626
6627}).call(TokenIterator.prototype);
6628
6629exports.TokenIterator = TokenIterator;
6630});
6631
6632ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(acequire, exports, module) {
6633
6634var oop = acequire("../../lib/oop");
6635var Behaviour = acequire("../behaviour").Behaviour;
6636var TokenIterator = acequire("../../token_iterator").TokenIterator;
6637var lang = acequire("../../lib/lang");
6638
6639var SAFE_INSERT_IN_TOKENS =
6640 ["text", "paren.rparen", "punctuation.operator"];
6641var SAFE_INSERT_BEFORE_TOKENS =
6642 ["text", "paren.rparen", "punctuation.operator", "comment"];
6643
6644var context;
6645var contextCache = {};
6646var defaultQuotes = {'"' : '"', "'" : "'"};
6647
6648var initContext = function(editor) {
6649 var id = -1;
6650 if (editor.multiSelect) {
6651 id = editor.selection.index;
6652 if (contextCache.rangeCount != editor.multiSelect.rangeCount)
6653 contextCache = {rangeCount: editor.multiSelect.rangeCount};
6654 }
6655 if (contextCache[id])
6656 return context = contextCache[id];
6657 context = contextCache[id] = {
6658 autoInsertedBrackets: 0,
6659 autoInsertedRow: -1,
6660 autoInsertedLineEnd: "",
6661 maybeInsertedBrackets: 0,
6662 maybeInsertedRow: -1,
6663 maybeInsertedLineStart: "",
6664 maybeInsertedLineEnd: ""
6665 };
6666};
6667
6668var getWrapped = function(selection, selected, opening, closing) {
6669 var rowDiff = selection.end.row - selection.start.row;
6670 return {
6671 text: opening + selected + closing,
6672 selection: [
6673 0,
6674 selection.start.column + 1,
6675 rowDiff,
6676 selection.end.column + (rowDiff ? 0 : 1)
6677 ]
6678 };
6679};
6680
6681var CstyleBehaviour = function(options) {
6682 this.add("braces", "insertion", function(state, action, editor, session, text) {
6683 var cursor = editor.getCursorPosition();
6684 var line = session.doc.getLine(cursor.row);
6685 if (text == '{') {
6686 initContext(editor);
6687 var selection = editor.getSelectionRange();
6688 var selected = session.doc.getTextRange(selection);
6689 if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
6690 return getWrapped(selection, selected, '{', '}');
6691 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6692 if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) {
6693 CstyleBehaviour.recordAutoInsert(editor, session, "}");
6694 return {
6695 text: '{}',
6696 selection: [1, 1]
6697 };
6698 } else {
6699 CstyleBehaviour.recordMaybeInsert(editor, session, "{");
6700 return {
6701 text: '{',
6702 selection: [1, 1]
6703 };
6704 }
6705 }
6706 } else if (text == '}') {
6707 initContext(editor);
6708 var rightChar = line.substring(cursor.column, cursor.column + 1);
6709 if (rightChar == '}') {
6710 var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
6711 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6712 CstyleBehaviour.popAutoInsertedClosing();
6713 return {
6714 text: '',
6715 selection: [1, 1]
6716 };
6717 }
6718 }
6719 } else if (text == "\n" || text == "\r\n") {
6720 initContext(editor);
6721 var closing = "";
6722 if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
6723 closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
6724 CstyleBehaviour.clearMaybeInsertedClosing();
6725 }
6726 var rightChar = line.substring(cursor.column, cursor.column + 1);
6727 if (rightChar === '}') {
6728 var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
6729 if (!openBracePos)
6730 return null;
6731 var next_indent = this.$getIndent(session.getLine(openBracePos.row));
6732 } else if (closing) {
6733 var next_indent = this.$getIndent(line);
6734 } else {
6735 CstyleBehaviour.clearMaybeInsertedClosing();
6736 return;
6737 }
6738 var indent = next_indent + session.getTabString();
6739
6740 return {
6741 text: '\n' + indent + '\n' + next_indent + closing,
6742 selection: [1, indent.length, 1, indent.length]
6743 };
6744 } else {
6745 CstyleBehaviour.clearMaybeInsertedClosing();
6746 }
6747 });
6748
6749 this.add("braces", "deletion", function(state, action, editor, session, range) {
6750 var selected = session.doc.getTextRange(range);
6751 if (!range.isMultiLine() && selected == '{') {
6752 initContext(editor);
6753 var line = session.doc.getLine(range.start.row);
6754 var rightChar = line.substring(range.end.column, range.end.column + 1);
6755 if (rightChar == '}') {
6756 range.end.column++;
6757 return range;
6758 } else {
6759 context.maybeInsertedBrackets--;
6760 }
6761 }
6762 });
6763
6764 this.add("parens", "insertion", function(state, action, editor, session, text) {
6765 if (text == '(') {
6766 initContext(editor);
6767 var selection = editor.getSelectionRange();
6768 var selected = session.doc.getTextRange(selection);
6769 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
6770 return getWrapped(selection, selected, '(', ')');
6771 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6772 CstyleBehaviour.recordAutoInsert(editor, session, ")");
6773 return {
6774 text: '()',
6775 selection: [1, 1]
6776 };
6777 }
6778 } else if (text == ')') {
6779 initContext(editor);
6780 var cursor = editor.getCursorPosition();
6781 var line = session.doc.getLine(cursor.row);
6782 var rightChar = line.substring(cursor.column, cursor.column + 1);
6783 if (rightChar == ')') {
6784 var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
6785 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6786 CstyleBehaviour.popAutoInsertedClosing();
6787 return {
6788 text: '',
6789 selection: [1, 1]
6790 };
6791 }
6792 }
6793 }
6794 });
6795
6796 this.add("parens", "deletion", function(state, action, editor, session, range) {
6797 var selected = session.doc.getTextRange(range);
6798 if (!range.isMultiLine() && selected == '(') {
6799 initContext(editor);
6800 var line = session.doc.getLine(range.start.row);
6801 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6802 if (rightChar == ')') {
6803 range.end.column++;
6804 return range;
6805 }
6806 }
6807 });
6808
6809 this.add("brackets", "insertion", function(state, action, editor, session, text) {
6810 if (text == '[') {
6811 initContext(editor);
6812 var selection = editor.getSelectionRange();
6813 var selected = session.doc.getTextRange(selection);
6814 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
6815 return getWrapped(selection, selected, '[', ']');
6816 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6817 CstyleBehaviour.recordAutoInsert(editor, session, "]");
6818 return {
6819 text: '[]',
6820 selection: [1, 1]
6821 };
6822 }
6823 } else if (text == ']') {
6824 initContext(editor);
6825 var cursor = editor.getCursorPosition();
6826 var line = session.doc.getLine(cursor.row);
6827 var rightChar = line.substring(cursor.column, cursor.column + 1);
6828 if (rightChar == ']') {
6829 var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
6830 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6831 CstyleBehaviour.popAutoInsertedClosing();
6832 return {
6833 text: '',
6834 selection: [1, 1]
6835 };
6836 }
6837 }
6838 }
6839 });
6840
6841 this.add("brackets", "deletion", function(state, action, editor, session, range) {
6842 var selected = session.doc.getTextRange(range);
6843 if (!range.isMultiLine() && selected == '[') {
6844 initContext(editor);
6845 var line = session.doc.getLine(range.start.row);
6846 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6847 if (rightChar == ']') {
6848 range.end.column++;
6849 return range;
6850 }
6851 }
6852 });
6853
6854 this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
6855 var quotes = session.$mode.$quotes || defaultQuotes;
6856 if (text.length == 1 && quotes[text]) {
6857 if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1)
6858 return;
6859 initContext(editor);
6860 var quote = text;
6861 var selection = editor.getSelectionRange();
6862 var selected = session.doc.getTextRange(selection);
6863 if (selected !== "" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) {
6864 return getWrapped(selection, selected, quote, quote);
6865 } else if (!selected) {
6866 var cursor = editor.getCursorPosition();
6867 var line = session.doc.getLine(cursor.row);
6868 var leftChar = line.substring(cursor.column-1, cursor.column);
6869 var rightChar = line.substring(cursor.column, cursor.column + 1);
6870
6871 var token = session.getTokenAt(cursor.row, cursor.column);
6872 var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);
6873 if (leftChar == "\\" && token && /escape/.test(token.type))
6874 return null;
6875
6876 var stringBefore = token && /string|escape/.test(token.type);
6877 var stringAfter = !rightToken || /string|escape/.test(rightToken.type);
6878
6879 var pair;
6880 if (rightChar == quote) {
6881 pair = stringBefore !== stringAfter;
6882 if (pair && /string\.end/.test(rightToken.type))
6883 pair = false;
6884 } else {
6885 if (stringBefore && !stringAfter)
6886 return null; // wrap string with different quote
6887 if (stringBefore && stringAfter)
6888 return null; // do not pair quotes inside strings
6889 var wordRe = session.$mode.tokenRe;
6890 wordRe.lastIndex = 0;
6891 var isWordBefore = wordRe.test(leftChar);
6892 wordRe.lastIndex = 0;
6893 var isWordAfter = wordRe.test(leftChar);
6894 if (isWordBefore || isWordAfter)
6895 return null; // before or after alphanumeric
6896 if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
6897 return null; // there is rightChar and it isn't closing
6898 pair = true;
6899 }
6900 return {
6901 text: pair ? quote + quote : "",
6902 selection: [1,1]
6903 };
6904 }
6905 }
6906 });
6907
6908 this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
6909 var selected = session.doc.getTextRange(range);
6910 if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
6911 initContext(editor);
6912 var line = session.doc.getLine(range.start.row);
6913 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6914 if (rightChar == selected) {
6915 range.end.column++;
6916 return range;
6917 }
6918 }
6919 });
6920
6921};
6922
6923
6924CstyleBehaviour.isSaneInsertion = function(editor, session) {
6925 var cursor = editor.getCursorPosition();
6926 var iterator = new TokenIterator(session, cursor.row, cursor.column);
6927 if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
6928 var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
6929 if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
6930 return false;
6931 }
6932 iterator.stepForward();
6933 return iterator.getCurrentTokenRow() !== cursor.row ||
6934 this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
6935};
6936
6937CstyleBehaviour.$matchTokenType = function(token, types) {
6938 return types.indexOf(token.type || token) > -1;
6939};
6940
6941CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
6942 var cursor = editor.getCursorPosition();
6943 var line = session.doc.getLine(cursor.row);
6944 if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
6945 context.autoInsertedBrackets = 0;
6946 context.autoInsertedRow = cursor.row;
6947 context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
6948 context.autoInsertedBrackets++;
6949};
6950
6951CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
6952 var cursor = editor.getCursorPosition();
6953 var line = session.doc.getLine(cursor.row);
6954 if (!this.isMaybeInsertedClosing(cursor, line))
6955 context.maybeInsertedBrackets = 0;
6956 context.maybeInsertedRow = cursor.row;
6957 context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
6958 context.maybeInsertedLineEnd = line.substr(cursor.column);
6959 context.maybeInsertedBrackets++;
6960};
6961
6962CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
6963 return context.autoInsertedBrackets > 0 &&
6964 cursor.row === context.autoInsertedRow &&
6965 bracket === context.autoInsertedLineEnd[0] &&
6966 line.substr(cursor.column) === context.autoInsertedLineEnd;
6967};
6968
6969CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
6970 return context.maybeInsertedBrackets > 0 &&
6971 cursor.row === context.maybeInsertedRow &&
6972 line.substr(cursor.column) === context.maybeInsertedLineEnd &&
6973 line.substr(0, cursor.column) == context.maybeInsertedLineStart;
6974};
6975
6976CstyleBehaviour.popAutoInsertedClosing = function() {
6977 context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
6978 context.autoInsertedBrackets--;
6979};
6980
6981CstyleBehaviour.clearMaybeInsertedClosing = function() {
6982 if (context) {
6983 context.maybeInsertedBrackets = 0;
6984 context.maybeInsertedRow = -1;
6985 }
6986};
6987
6988
6989
6990oop.inherits(CstyleBehaviour, Behaviour);
6991
6992exports.CstyleBehaviour = CstyleBehaviour;
6993});
6994
6995ace.define("ace/unicode",["require","exports","module"], function(acequire, exports, module) {
6996exports.packages = {};
6997
6998addUnicodePackage({
6999 L: "0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",
7000 Ll: "0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",
7001 Lu: "0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",
7002 Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",
7003 Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",
7004 Lo: "01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",
7005 M: "0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",
7006 Mn: "0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",
7007 Mc: "0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",
7008 Me: "0488048906DE20DD-20E020E2-20E4A670-A672",
7009 N: "0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",
7010 Nd: "0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",
7011 Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",
7012 No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",
7013 P: "0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",
7014 Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",
7015 Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",
7016 Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",
7017 Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",
7018 Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21",
7019 Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F",
7020 Po: "0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",
7021 S: "0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",
7022 Sm: "002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",
7023 Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",
7024 Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",
7025 So: "00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",
7026 Z: "002000A01680180E2000-200A20282029202F205F3000",
7027 Zs: "002000A01680180E2000-200A202F205F3000",
7028 Zl: "2028",
7029 Zp: "2029",
7030 C: "0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",
7031 Cc: "0000-001F007F-009F",
7032 Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",
7033 Co: "E000-F8FF",
7034 Cs: "D800-DFFF",
7035 Cn: "03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"
7036});
7037
7038function addUnicodePackage (pack) {
7039 var codePoint = /\w{4}/g;
7040 for (var name in pack)
7041 exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
7042}
7043
7044});
7045
7046ace.define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour/cstyle","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"], function(acequire, exports, module) {
7047
7048var Tokenizer = acequire("../tokenizer").Tokenizer;
7049var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
7050var CstyleBehaviour = acequire("./behaviour/cstyle").CstyleBehaviour;
7051var unicode = acequire("../unicode");
7052var lang = acequire("../lib/lang");
7053var TokenIterator = acequire("../token_iterator").TokenIterator;
7054var Range = acequire("../range").Range;
7055
7056var Mode = function() {
7057 this.HighlightRules = TextHighlightRules;
7058};
7059
7060(function() {
7061 this.$defaultBehaviour = new CstyleBehaviour();
7062
7063 this.tokenRe = new RegExp("^["
7064 + unicode.packages.L
7065 + unicode.packages.Mn + unicode.packages.Mc
7066 + unicode.packages.Nd
7067 + unicode.packages.Pc + "\\$_]+", "g"
7068 );
7069
7070 this.nonTokenRe = new RegExp("^(?:[^"
7071 + unicode.packages.L
7072 + unicode.packages.Mn + unicode.packages.Mc
7073 + unicode.packages.Nd
7074 + unicode.packages.Pc + "\\$_]|\\s])+", "g"
7075 );
7076
7077 this.getTokenizer = function() {
7078 if (!this.$tokenizer) {
7079 this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig);
7080 this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());
7081 }
7082 return this.$tokenizer;
7083 };
7084
7085 this.lineCommentStart = "";
7086 this.blockComment = "";
7087
7088 this.toggleCommentLines = function(state, session, startRow, endRow) {
7089 var doc = session.doc;
7090
7091 var ignoreBlankLines = true;
7092 var shouldRemove = true;
7093 var minIndent = Infinity;
7094 var tabSize = session.getTabSize();
7095 var insertAtTabStop = false;
7096
7097 if (!this.lineCommentStart) {
7098 if (!this.blockComment)
7099 return false;
7100 var lineCommentStart = this.blockComment.start;
7101 var lineCommentEnd = this.blockComment.end;
7102 var regexpStart = new RegExp("^(\\s*)(?:" + lang.escapeRegExp(lineCommentStart) + ")");
7103 var regexpEnd = new RegExp("(?:" + lang.escapeRegExp(lineCommentEnd) + ")\\s*$");
7104
7105 var comment = function(line, i) {
7106 if (testRemove(line, i))
7107 return;
7108 if (!ignoreBlankLines || /\S/.test(line)) {
7109 doc.insertInLine({row: i, column: line.length}, lineCommentEnd);
7110 doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
7111 }
7112 };
7113
7114 var uncomment = function(line, i) {
7115 var m;
7116 if (m = line.match(regexpEnd))
7117 doc.removeInLine(i, line.length - m[0].length, line.length);
7118 if (m = line.match(regexpStart))
7119 doc.removeInLine(i, m[1].length, m[0].length);
7120 };
7121
7122 var testRemove = function(line, row) {
7123 if (regexpStart.test(line))
7124 return true;
7125 var tokens = session.getTokens(row);
7126 for (var i = 0; i < tokens.length; i++) {
7127 if (tokens[i].type === "comment")
7128 return true;
7129 }
7130 };
7131 } else {
7132 if (Array.isArray(this.lineCommentStart)) {
7133 var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|");
7134 var lineCommentStart = this.lineCommentStart[0];
7135 } else {
7136 var regexpStart = lang.escapeRegExp(this.lineCommentStart);
7137 var lineCommentStart = this.lineCommentStart;
7138 }
7139 regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?");
7140
7141 insertAtTabStop = session.getUseSoftTabs();
7142
7143 var uncomment = function(line, i) {
7144 var m = line.match(regexpStart);
7145 if (!m) return;
7146 var start = m[1].length, end = m[0].length;
7147 if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ")
7148 end--;
7149 doc.removeInLine(i, start, end);
7150 };
7151 var commentWithSpace = lineCommentStart + " ";
7152 var comment = function(line, i) {
7153 if (!ignoreBlankLines || /\S/.test(line)) {
7154 if (shouldInsertSpace(line, minIndent, minIndent))
7155 doc.insertInLine({row: i, column: minIndent}, commentWithSpace);
7156 else
7157 doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
7158 }
7159 };
7160 var testRemove = function(line, i) {
7161 return regexpStart.test(line);
7162 };
7163
7164 var shouldInsertSpace = function(line, before, after) {
7165 var spaces = 0;
7166 while (before-- && line.charAt(before) == " ")
7167 spaces++;
7168 if (spaces % tabSize != 0)
7169 return false;
7170 var spaces = 0;
7171 while (line.charAt(after++) == " ")
7172 spaces++;
7173 if (tabSize > 2)
7174 return spaces % tabSize != tabSize - 1;
7175 else
7176 return spaces % tabSize == 0;
7177 };
7178 }
7179
7180 function iter(fun) {
7181 for (var i = startRow; i <= endRow; i++)
7182 fun(doc.getLine(i), i);
7183 }
7184
7185
7186 var minEmptyLength = Infinity;
7187 iter(function(line, i) {
7188 var indent = line.search(/\S/);
7189 if (indent !== -1) {
7190 if (indent < minIndent)
7191 minIndent = indent;
7192 if (shouldRemove && !testRemove(line, i))
7193 shouldRemove = false;
7194 } else if (minEmptyLength > line.length) {
7195 minEmptyLength = line.length;
7196 }
7197 });
7198
7199 if (minIndent == Infinity) {
7200 minIndent = minEmptyLength;
7201 ignoreBlankLines = false;
7202 shouldRemove = false;
7203 }
7204
7205 if (insertAtTabStop && minIndent % tabSize != 0)
7206 minIndent = Math.floor(minIndent / tabSize) * tabSize;
7207
7208 iter(shouldRemove ? uncomment : comment);
7209 };
7210
7211 this.toggleBlockComment = function(state, session, range, cursor) {
7212 var comment = this.blockComment;
7213 if (!comment)
7214 return;
7215 if (!comment.start && comment[0])
7216 comment = comment[0];
7217
7218 var iterator = new TokenIterator(session, cursor.row, cursor.column);
7219 var token = iterator.getCurrentToken();
7220
7221 session.selection;
7222 var initialRange = session.selection.toOrientedRange();
7223 var startRow, colDiff;
7224
7225 if (token && /comment/.test(token.type)) {
7226 var startRange, endRange;
7227 while (token && /comment/.test(token.type)) {
7228 var i = token.value.indexOf(comment.start);
7229 if (i != -1) {
7230 var row = iterator.getCurrentTokenRow();
7231 var column = iterator.getCurrentTokenColumn() + i;
7232 startRange = new Range(row, column, row, column + comment.start.length);
7233 break;
7234 }
7235 token = iterator.stepBackward();
7236 }
7237
7238 var iterator = new TokenIterator(session, cursor.row, cursor.column);
7239 var token = iterator.getCurrentToken();
7240 while (token && /comment/.test(token.type)) {
7241 var i = token.value.indexOf(comment.end);
7242 if (i != -1) {
7243 var row = iterator.getCurrentTokenRow();
7244 var column = iterator.getCurrentTokenColumn() + i;
7245 endRange = new Range(row, column, row, column + comment.end.length);
7246 break;
7247 }
7248 token = iterator.stepForward();
7249 }
7250 if (endRange)
7251 session.remove(endRange);
7252 if (startRange) {
7253 session.remove(startRange);
7254 startRow = startRange.start.row;
7255 colDiff = -comment.start.length;
7256 }
7257 } else {
7258 colDiff = comment.start.length;
7259 startRow = range.start.row;
7260 session.insert(range.end, comment.end);
7261 session.insert(range.start, comment.start);
7262 }
7263 if (initialRange.start.row == startRow)
7264 initialRange.start.column += colDiff;
7265 if (initialRange.end.row == startRow)
7266 initialRange.end.column += colDiff;
7267 session.selection.fromOrientedRange(initialRange);
7268 };
7269
7270 this.getNextLineIndent = function(state, line, tab) {
7271 return this.$getIndent(line);
7272 };
7273
7274 this.checkOutdent = function(state, line, input) {
7275 return false;
7276 };
7277
7278 this.autoOutdent = function(state, doc, row) {
7279 };
7280
7281 this.$getIndent = function(line) {
7282 return line.match(/^\s*/)[0];
7283 };
7284
7285 this.createWorker = function(session) {
7286 return null;
7287 };
7288
7289 this.createModeDelegates = function (mapping) {
7290 this.$embeds = [];
7291 this.$modes = {};
7292 for (var i in mapping) {
7293 if (mapping[i]) {
7294 this.$embeds.push(i);
7295 this.$modes[i] = new mapping[i]();
7296 }
7297 }
7298
7299 var delegations = ["toggleBlockComment", "toggleCommentLines", "getNextLineIndent",
7300 "checkOutdent", "autoOutdent", "transformAction", "getCompletions"];
7301
7302 for (var i = 0; i < delegations.length; i++) {
7303 (function(scope) {
7304 var functionName = delegations[i];
7305 var defaultHandler = scope[functionName];
7306 scope[delegations[i]] = function() {
7307 return this.$delegator(functionName, arguments, defaultHandler);
7308 };
7309 }(this));
7310 }
7311 };
7312
7313 this.$delegator = function(method, args, defaultHandler) {
7314 var state = args[0];
7315 if (typeof state != "string")
7316 state = state[0];
7317 for (var i = 0; i < this.$embeds.length; i++) {
7318 if (!this.$modes[this.$embeds[i]]) continue;
7319
7320 var split = state.split(this.$embeds[i]);
7321 if (!split[0] && split[1]) {
7322 args[0] = split[1];
7323 var mode = this.$modes[this.$embeds[i]];
7324 return mode[method].apply(mode, args);
7325 }
7326 }
7327 var ret = defaultHandler.apply(this, args);
7328 return defaultHandler ? ret : undefined;
7329 };
7330
7331 this.transformAction = function(state, action, editor, session, param) {
7332 if (this.$behaviour) {
7333 var behaviours = this.$behaviour.getBehaviours();
7334 for (var key in behaviours) {
7335 if (behaviours[key][action]) {
7336 var ret = behaviours[key][action].apply(this, arguments);
7337 if (ret) {
7338 return ret;
7339 }
7340 }
7341 }
7342 }
7343 };
7344
7345 this.getKeywords = function(append) {
7346 if (!this.completionKeywords) {
7347 var rules = this.$tokenizer.rules;
7348 var completionKeywords = [];
7349 for (var rule in rules) {
7350 var ruleItr = rules[rule];
7351 for (var r = 0, l = ruleItr.length; r < l; r++) {
7352 if (typeof ruleItr[r].token === "string") {
7353 if (/keyword|support|storage/.test(ruleItr[r].token))
7354 completionKeywords.push(ruleItr[r].regex);
7355 }
7356 else if (typeof ruleItr[r].token === "object") {
7357 for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {
7358 if (/keyword|support|storage/.test(ruleItr[r].token[a])) {
7359 var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a];
7360 completionKeywords.push(rule.substr(1, rule.length - 2));
7361 }
7362 }
7363 }
7364 }
7365 }
7366 this.completionKeywords = completionKeywords;
7367 }
7368 if (!append)
7369 return this.$keywordList;
7370 return completionKeywords.concat(this.$keywordList || []);
7371 };
7372
7373 this.$createKeywordList = function() {
7374 if (!this.$highlightRules)
7375 this.getTokenizer();
7376 return this.$keywordList = this.$highlightRules.$keywordList || [];
7377 };
7378
7379 this.getCompletions = function(state, session, pos, prefix) {
7380 var keywords = this.$keywordList || this.$createKeywordList();
7381 return keywords.map(function(word) {
7382 return {
7383 name: word,
7384 value: word,
7385 score: 0,
7386 meta: "keyword"
7387 };
7388 });
7389 };
7390
7391 this.$id = "ace/mode/text";
7392}).call(Mode.prototype);
7393
7394exports.Mode = Mode;
7395});
7396
7397ace.define("ace/apply_delta",["require","exports","module"], function(acequire, exports, module) {
7398
7399exports.applyDelta = function(docLines, delta, doNotValidate) {
7400
7401 var row = delta.start.row;
7402 var startColumn = delta.start.column;
7403 var line = docLines[row] || "";
7404 switch (delta.action) {
7405 case "insert":
7406 var lines = delta.lines;
7407 if (lines.length === 1) {
7408 docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
7409 } else {
7410 var args = [row, 1].concat(delta.lines);
7411 docLines.splice.apply(docLines, args);
7412 docLines[row] = line.substring(0, startColumn) + docLines[row];
7413 docLines[row + delta.lines.length - 1] += line.substring(startColumn);
7414 }
7415 break;
7416 case "remove":
7417 var endColumn = delta.end.column;
7418 var endRow = delta.end.row;
7419 if (row === endRow) {
7420 docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);
7421 } else {
7422 docLines.splice(
7423 row, endRow - row + 1,
7424 line.substring(0, startColumn) + docLines[endRow].substring(endColumn)
7425 );
7426 }
7427 break;
7428 }
7429};
7430});
7431
7432ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(acequire, exports, module) {
7433
7434var oop = acequire("./lib/oop");
7435var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
7436
7437var Anchor = exports.Anchor = function(doc, row, column) {
7438 this.$onChange = this.onChange.bind(this);
7439 this.attach(doc);
7440
7441 if (typeof column == "undefined")
7442 this.setPosition(row.row, row.column);
7443 else
7444 this.setPosition(row, column);
7445};
7446
7447(function() {
7448
7449 oop.implement(this, EventEmitter);
7450 this.getPosition = function() {
7451 return this.$clipPositionToDocument(this.row, this.column);
7452 };
7453 this.getDocument = function() {
7454 return this.document;
7455 };
7456 this.$insertRight = false;
7457 this.onChange = function(delta) {
7458 if (delta.start.row == delta.end.row && delta.start.row != this.row)
7459 return;
7460
7461 if (delta.start.row > this.row)
7462 return;
7463
7464 var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);
7465 this.setPosition(point.row, point.column, true);
7466 };
7467
7468 function $pointsInOrder(point1, point2, equalPointsInOrder) {
7469 var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;
7470 return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);
7471 }
7472
7473 function $getTransformedPoint(delta, point, moveIfEqual) {
7474 var deltaIsInsert = delta.action == "insert";
7475 var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row);
7476 var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);
7477 var deltaStart = delta.start;
7478 var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.
7479 if ($pointsInOrder(point, deltaStart, moveIfEqual)) {
7480 return {
7481 row: point.row,
7482 column: point.column
7483 };
7484 }
7485 if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {
7486 return {
7487 row: point.row + deltaRowShift,
7488 column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)
7489 };
7490 }
7491
7492 return {
7493 row: deltaStart.row,
7494 column: deltaStart.column
7495 };
7496 }
7497 this.setPosition = function(row, column, noClip) {
7498 var pos;
7499 if (noClip) {
7500 pos = {
7501 row: row,
7502 column: column
7503 };
7504 } else {
7505 pos = this.$clipPositionToDocument(row, column);
7506 }
7507
7508 if (this.row == pos.row && this.column == pos.column)
7509 return;
7510
7511 var old = {
7512 row: this.row,
7513 column: this.column
7514 };
7515
7516 this.row = pos.row;
7517 this.column = pos.column;
7518 this._signal("change", {
7519 old: old,
7520 value: pos
7521 });
7522 };
7523 this.detach = function() {
7524 this.document.removeEventListener("change", this.$onChange);
7525 };
7526 this.attach = function(doc) {
7527 this.document = doc || this.document;
7528 this.document.on("change", this.$onChange);
7529 };
7530 this.$clipPositionToDocument = function(row, column) {
7531 var pos = {};
7532
7533 if (row >= this.document.getLength()) {
7534 pos.row = Math.max(0, this.document.getLength() - 1);
7535 pos.column = this.document.getLine(pos.row).length;
7536 }
7537 else if (row < 0) {
7538 pos.row = 0;
7539 pos.column = 0;
7540 }
7541 else {
7542 pos.row = row;
7543 pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
7544 }
7545
7546 if (column < 0)
7547 pos.column = 0;
7548
7549 return pos;
7550 };
7551
7552}).call(Anchor.prototype);
7553
7554});
7555
7556ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"], function(acequire, exports, module) {
7557
7558var oop = acequire("./lib/oop");
7559var applyDelta = acequire("./apply_delta").applyDelta;
7560var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
7561var Range = acequire("./range").Range;
7562var Anchor = acequire("./anchor").Anchor;
7563
7564var Document = function(textOrLines) {
7565 this.$lines = [""];
7566 if (textOrLines.length === 0) {
7567 this.$lines = [""];
7568 } else if (Array.isArray(textOrLines)) {
7569 this.insertMergedLines({row: 0, column: 0}, textOrLines);
7570 } else {
7571 this.insert({row: 0, column:0}, textOrLines);
7572 }
7573};
7574
7575(function() {
7576
7577 oop.implement(this, EventEmitter);
7578 this.setValue = function(text) {
7579 var len = this.getLength() - 1;
7580 this.remove(new Range(0, 0, len, this.getLine(len).length));
7581 this.insert({row: 0, column: 0}, text);
7582 };
7583 this.getValue = function() {
7584 return this.getAllLines().join(this.getNewLineCharacter());
7585 };
7586 this.createAnchor = function(row, column) {
7587 return new Anchor(this, row, column);
7588 };
7589 if ("aaa".split(/a/).length === 0) {
7590 this.$split = function(text) {
7591 return text.replace(/\r\n|\r/g, "\n").split("\n");
7592 };
7593 } else {
7594 this.$split = function(text) {
7595 return text.split(/\r\n|\r|\n/);
7596 };
7597 }
7598
7599
7600 this.$detectNewLine = function(text) {
7601 var match = text.match(/^.*?(\r\n|\r|\n)/m);
7602 this.$autoNewLine = match ? match[1] : "\n";
7603 this._signal("changeNewLineMode");
7604 };
7605 this.getNewLineCharacter = function() {
7606 switch (this.$newLineMode) {
7607 case "windows":
7608 return "\r\n";
7609 case "unix":
7610 return "\n";
7611 default:
7612 return this.$autoNewLine || "\n";
7613 }
7614 };
7615
7616 this.$autoNewLine = "";
7617 this.$newLineMode = "auto";
7618 this.setNewLineMode = function(newLineMode) {
7619 if (this.$newLineMode === newLineMode)
7620 return;
7621
7622 this.$newLineMode = newLineMode;
7623 this._signal("changeNewLineMode");
7624 };
7625 this.getNewLineMode = function() {
7626 return this.$newLineMode;
7627 };
7628 this.isNewLine = function(text) {
7629 return (text == "\r\n" || text == "\r" || text == "\n");
7630 };
7631 this.getLine = function(row) {
7632 return this.$lines[row] || "";
7633 };
7634 this.getLines = function(firstRow, lastRow) {
7635 return this.$lines.slice(firstRow, lastRow + 1);
7636 };
7637 this.getAllLines = function() {
7638 return this.getLines(0, this.getLength());
7639 };
7640 this.getLength = function() {
7641 return this.$lines.length;
7642 };
7643 this.getTextRange = function(range) {
7644 return this.getLinesForRange(range).join(this.getNewLineCharacter());
7645 };
7646 this.getLinesForRange = function(range) {
7647 var lines;
7648 if (range.start.row === range.end.row) {
7649 lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];
7650 } else {
7651 lines = this.getLines(range.start.row, range.end.row);
7652 lines[0] = (lines[0] || "").substring(range.start.column);
7653 var l = lines.length - 1;
7654 if (range.end.row - range.start.row == l)
7655 lines[l] = lines[l].substring(0, range.end.column);
7656 }
7657 return lines;
7658 };
7659 this.insertLines = function(row, lines) {
7660 console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead.");
7661 return this.insertFullLines(row, lines);
7662 };
7663 this.removeLines = function(firstRow, lastRow) {
7664 console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead.");
7665 return this.removeFullLines(firstRow, lastRow);
7666 };
7667 this.insertNewLine = function(position) {
7668 console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.");
7669 return this.insertMergedLines(position, ["", ""]);
7670 };
7671 this.insert = function(position, text) {
7672 if (this.getLength() <= 1)
7673 this.$detectNewLine(text);
7674
7675 return this.insertMergedLines(position, this.$split(text));
7676 };
7677 this.insertInLine = function(position, text) {
7678 var start = this.clippedPos(position.row, position.column);
7679 var end = this.pos(position.row, position.column + text.length);
7680
7681 this.applyDelta({
7682 start: start,
7683 end: end,
7684 action: "insert",
7685 lines: [text]
7686 }, true);
7687
7688 return this.clonePos(end);
7689 };
7690
7691 this.clippedPos = function(row, column) {
7692 var length = this.getLength();
7693 if (row === undefined) {
7694 row = length;
7695 } else if (row < 0) {
7696 row = 0;
7697 } else if (row >= length) {
7698 row = length - 1;
7699 column = undefined;
7700 }
7701 var line = this.getLine(row);
7702 if (column == undefined)
7703 column = line.length;
7704 column = Math.min(Math.max(column, 0), line.length);
7705 return {row: row, column: column};
7706 };
7707
7708 this.clonePos = function(pos) {
7709 return {row: pos.row, column: pos.column};
7710 };
7711
7712 this.pos = function(row, column) {
7713 return {row: row, column: column};
7714 };
7715
7716 this.$clipPosition = function(position) {
7717 var length = this.getLength();
7718 if (position.row >= length) {
7719 position.row = Math.max(0, length - 1);
7720 position.column = this.getLine(length - 1).length;
7721 } else {
7722 position.row = Math.max(0, position.row);
7723 position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);
7724 }
7725 return position;
7726 };
7727 this.insertFullLines = function(row, lines) {
7728 row = Math.min(Math.max(row, 0), this.getLength());
7729 var column = 0;
7730 if (row < this.getLength()) {
7731 lines = lines.concat([""]);
7732 column = 0;
7733 } else {
7734 lines = [""].concat(lines);
7735 row--;
7736 column = this.$lines[row].length;
7737 }
7738 this.insertMergedLines({row: row, column: column}, lines);
7739 };
7740 this.insertMergedLines = function(position, lines) {
7741 var start = this.clippedPos(position.row, position.column);
7742 var end = {
7743 row: start.row + lines.length - 1,
7744 column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length
7745 };
7746
7747 this.applyDelta({
7748 start: start,
7749 end: end,
7750 action: "insert",
7751 lines: lines
7752 });
7753
7754 return this.clonePos(end);
7755 };
7756 this.remove = function(range) {
7757 var start = this.clippedPos(range.start.row, range.start.column);
7758 var end = this.clippedPos(range.end.row, range.end.column);
7759 this.applyDelta({
7760 start: start,
7761 end: end,
7762 action: "remove",
7763 lines: this.getLinesForRange({start: start, end: end})
7764 });
7765 return this.clonePos(start);
7766 };
7767 this.removeInLine = function(row, startColumn, endColumn) {
7768 var start = this.clippedPos(row, startColumn);
7769 var end = this.clippedPos(row, endColumn);
7770
7771 this.applyDelta({
7772 start: start,
7773 end: end,
7774 action: "remove",
7775 lines: this.getLinesForRange({start: start, end: end})
7776 }, true);
7777
7778 return this.clonePos(start);
7779 };
7780 this.removeFullLines = function(firstRow, lastRow) {
7781 firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);
7782 lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1);
7783 var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;
7784 var deleteLastNewLine = lastRow < this.getLength() - 1;
7785 var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow );
7786 var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 );
7787 var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow );
7788 var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length );
7789 var range = new Range(startRow, startCol, endRow, endCol);
7790 var deletedLines = this.$lines.slice(firstRow, lastRow + 1);
7791
7792 this.applyDelta({
7793 start: range.start,
7794 end: range.end,
7795 action: "remove",
7796 lines: this.getLinesForRange(range)
7797 });
7798 return deletedLines;
7799 };
7800 this.removeNewLine = function(row) {
7801 if (row < this.getLength() - 1 && row >= 0) {
7802 this.applyDelta({
7803 start: this.pos(row, this.getLine(row).length),
7804 end: this.pos(row + 1, 0),
7805 action: "remove",
7806 lines: ["", ""]
7807 });
7808 }
7809 };
7810 this.replace = function(range, text) {
7811 if (!(range instanceof Range))
7812 range = Range.fromPoints(range.start, range.end);
7813 if (text.length === 0 && range.isEmpty())
7814 return range.start;
7815 if (text == this.getTextRange(range))
7816 return range.end;
7817
7818 this.remove(range);
7819 var end;
7820 if (text) {
7821 end = this.insert(range.start, text);
7822 }
7823 else {
7824 end = range.start;
7825 }
7826
7827 return end;
7828 };
7829 this.applyDeltas = function(deltas) {
7830 for (var i=0; i<deltas.length; i++) {
7831 this.applyDelta(deltas[i]);
7832 }
7833 };
7834 this.revertDeltas = function(deltas) {
7835 for (var i=deltas.length-1; i>=0; i--) {
7836 this.revertDelta(deltas[i]);
7837 }
7838 };
7839 this.applyDelta = function(delta, doNotValidate) {
7840 var isInsert = delta.action == "insert";
7841 if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]
7842 : !Range.comparePoints(delta.start, delta.end)) {
7843 return;
7844 }
7845
7846 if (isInsert && delta.lines.length > 20000)
7847 this.$splitAndapplyLargeDelta(delta, 20000);
7848 applyDelta(this.$lines, delta, doNotValidate);
7849 this._signal("change", delta);
7850 };
7851
7852 this.$splitAndapplyLargeDelta = function(delta, MAX) {
7853 var lines = delta.lines;
7854 var l = lines.length;
7855 var row = delta.start.row;
7856 var column = delta.start.column;
7857 var from = 0, to = 0;
7858 do {
7859 from = to;
7860 to += MAX - 1;
7861 var chunk = lines.slice(from, to);
7862 if (to > l) {
7863 delta.lines = chunk;
7864 delta.start.row = row + from;
7865 delta.start.column = column;
7866 break;
7867 }
7868 chunk.push("");
7869 this.applyDelta({
7870 start: this.pos(row + from, column),
7871 end: this.pos(row + to, column = 0),
7872 action: delta.action,
7873 lines: chunk
7874 }, true);
7875 } while(true);
7876 };
7877 this.revertDelta = function(delta) {
7878 this.applyDelta({
7879 start: this.clonePos(delta.start),
7880 end: this.clonePos(delta.end),
7881 action: (delta.action == "insert" ? "remove" : "insert"),
7882 lines: delta.lines.slice()
7883 });
7884 };
7885 this.indexToPosition = function(index, startRow) {
7886 var lines = this.$lines || this.getAllLines();
7887 var newlineLength = this.getNewLineCharacter().length;
7888 for (var i = startRow || 0, l = lines.length; i < l; i++) {
7889 index -= lines[i].length + newlineLength;
7890 if (index < 0)
7891 return {row: i, column: index + lines[i].length + newlineLength};
7892 }
7893 return {row: l-1, column: lines[l-1].length};
7894 };
7895 this.positionToIndex = function(pos, startRow) {
7896 var lines = this.$lines || this.getAllLines();
7897 var newlineLength = this.getNewLineCharacter().length;
7898 var index = 0;
7899 var row = Math.min(pos.row, lines.length);
7900 for (var i = startRow || 0; i < row; ++i)
7901 index += lines[i].length + newlineLength;
7902
7903 return index + pos.column;
7904 };
7905
7906}).call(Document.prototype);
7907
7908exports.Document = Document;
7909});
7910
7911ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(acequire, exports, module) {
7912
7913var oop = acequire("./lib/oop");
7914var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
7915
7916var BackgroundTokenizer = function(tokenizer, editor) {
7917 this.running = false;
7918 this.lines = [];
7919 this.states = [];
7920 this.currentLine = 0;
7921 this.tokenizer = tokenizer;
7922
7923 var self = this;
7924
7925 this.$worker = function() {
7926 if (!self.running) { return; }
7927
7928 var workerStart = new Date();
7929 var currentLine = self.currentLine;
7930 var endLine = -1;
7931 var doc = self.doc;
7932
7933 var startLine = currentLine;
7934 while (self.lines[currentLine])
7935 currentLine++;
7936
7937 var len = doc.getLength();
7938 var processedLines = 0;
7939 self.running = false;
7940 while (currentLine < len) {
7941 self.$tokenizeRow(currentLine);
7942 endLine = currentLine;
7943 do {
7944 currentLine++;
7945 } while (self.lines[currentLine]);
7946 processedLines ++;
7947 if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) {
7948 self.running = setTimeout(self.$worker, 20);
7949 break;
7950 }
7951 }
7952 self.currentLine = currentLine;
7953
7954 if (endLine == -1)
7955 endLine = currentLine;
7956
7957 if (startLine <= endLine)
7958 self.fireUpdateEvent(startLine, endLine);
7959 };
7960};
7961
7962(function(){
7963
7964 oop.implement(this, EventEmitter);
7965 this.setTokenizer = function(tokenizer) {
7966 this.tokenizer = tokenizer;
7967 this.lines = [];
7968 this.states = [];
7969
7970 this.start(0);
7971 };
7972 this.setDocument = function(doc) {
7973 this.doc = doc;
7974 this.lines = [];
7975 this.states = [];
7976
7977 this.stop();
7978 };
7979 this.fireUpdateEvent = function(firstRow, lastRow) {
7980 var data = {
7981 first: firstRow,
7982 last: lastRow
7983 };
7984 this._signal("update", {data: data});
7985 };
7986 this.start = function(startRow) {
7987 this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
7988 this.lines.splice(this.currentLine, this.lines.length);
7989 this.states.splice(this.currentLine, this.states.length);
7990
7991 this.stop();
7992 this.running = setTimeout(this.$worker, 700);
7993 };
7994
7995 this.scheduleStart = function() {
7996 if (!this.running)
7997 this.running = setTimeout(this.$worker, 700);
7998 };
7999
8000 this.$updateOnChange = function(delta) {
8001 var startRow = delta.start.row;
8002 var len = delta.end.row - startRow;
8003
8004 if (len === 0) {
8005 this.lines[startRow] = null;
8006 } else if (delta.action == "remove") {
8007 this.lines.splice(startRow, len + 1, null);
8008 this.states.splice(startRow, len + 1, null);
8009 } else {
8010 var args = Array(len + 1);
8011 args.unshift(startRow, 1);
8012 this.lines.splice.apply(this.lines, args);
8013 this.states.splice.apply(this.states, args);
8014 }
8015
8016 this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
8017
8018 this.stop();
8019 };
8020 this.stop = function() {
8021 if (this.running)
8022 clearTimeout(this.running);
8023 this.running = false;
8024 };
8025 this.getTokens = function(row) {
8026 return this.lines[row] || this.$tokenizeRow(row);
8027 };
8028 this.getState = function(row) {
8029 if (this.currentLine == row)
8030 this.$tokenizeRow(row);
8031 return this.states[row] || "start";
8032 };
8033
8034 this.$tokenizeRow = function(row) {
8035 var line = this.doc.getLine(row);
8036 var state = this.states[row - 1];
8037
8038 var data = this.tokenizer.getLineTokens(line, state, row);
8039
8040 if (this.states[row] + "" !== data.state + "") {
8041 this.states[row] = data.state;
8042 this.lines[row + 1] = null;
8043 if (this.currentLine > row + 1)
8044 this.currentLine = row + 1;
8045 } else if (this.currentLine == row) {
8046 this.currentLine = row + 1;
8047 }
8048
8049 return this.lines[row] = data.tokens;
8050 };
8051
8052}).call(BackgroundTokenizer.prototype);
8053
8054exports.BackgroundTokenizer = BackgroundTokenizer;
8055});
8056
8057ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(acequire, exports, module) {
8058
8059var lang = acequire("./lib/lang");
8060acequire("./lib/oop");
8061var Range = acequire("./range").Range;
8062
8063var SearchHighlight = function(regExp, clazz, type) {
8064 this.setRegexp(regExp);
8065 this.clazz = clazz;
8066 this.type = type || "text";
8067};
8068
8069(function() {
8070 this.MAX_RANGES = 500;
8071
8072 this.setRegexp = function(regExp) {
8073 if (this.regExp+"" == regExp+"")
8074 return;
8075 this.regExp = regExp;
8076 this.cache = [];
8077 };
8078
8079 this.update = function(html, markerLayer, session, config) {
8080 if (!this.regExp)
8081 return;
8082 var start = config.firstRow, end = config.lastRow;
8083
8084 for (var i = start; i <= end; i++) {
8085 var ranges = this.cache[i];
8086 if (ranges == null) {
8087 ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);
8088 if (ranges.length > this.MAX_RANGES)
8089 ranges = ranges.slice(0, this.MAX_RANGES);
8090 ranges = ranges.map(function(match) {
8091 return new Range(i, match.offset, i, match.offset + match.length);
8092 });
8093 this.cache[i] = ranges.length ? ranges : "";
8094 }
8095
8096 for (var j = ranges.length; j --; ) {
8097 markerLayer.drawSingleLineMarker(
8098 html, ranges[j].toScreenRange(session), this.clazz, config);
8099 }
8100 }
8101 };
8102
8103}).call(SearchHighlight.prototype);
8104
8105exports.SearchHighlight = SearchHighlight;
8106});
8107
8108ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"], function(acequire, exports, module) {
8109
8110var Range = acequire("../range").Range;
8111function FoldLine(foldData, folds) {
8112 this.foldData = foldData;
8113 if (Array.isArray(folds)) {
8114 this.folds = folds;
8115 } else {
8116 folds = this.folds = [ folds ];
8117 }
8118
8119 var last = folds[folds.length - 1];
8120 this.range = new Range(folds[0].start.row, folds[0].start.column,
8121 last.end.row, last.end.column);
8122 this.start = this.range.start;
8123 this.end = this.range.end;
8124
8125 this.folds.forEach(function(fold) {
8126 fold.setFoldLine(this);
8127 }, this);
8128}
8129
8130(function() {
8131 this.shiftRow = function(shift) {
8132 this.start.row += shift;
8133 this.end.row += shift;
8134 this.folds.forEach(function(fold) {
8135 fold.start.row += shift;
8136 fold.end.row += shift;
8137 });
8138 };
8139
8140 this.addFold = function(fold) {
8141 if (fold.sameRow) {
8142 if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
8143 throw new Error("Can't add a fold to this FoldLine as it has no connection");
8144 }
8145 this.folds.push(fold);
8146 this.folds.sort(function(a, b) {
8147 return -a.range.compareEnd(b.start.row, b.start.column);
8148 });
8149 if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
8150 this.end.row = fold.end.row;
8151 this.end.column = fold.end.column;
8152 } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
8153 this.start.row = fold.start.row;
8154 this.start.column = fold.start.column;
8155 }
8156 } else if (fold.start.row == this.end.row) {
8157 this.folds.push(fold);
8158 this.end.row = fold.end.row;
8159 this.end.column = fold.end.column;
8160 } else if (fold.end.row == this.start.row) {
8161 this.folds.unshift(fold);
8162 this.start.row = fold.start.row;
8163 this.start.column = fold.start.column;
8164 } else {
8165 throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
8166 }
8167 fold.foldLine = this;
8168 };
8169
8170 this.containsRow = function(row) {
8171 return row >= this.start.row && row <= this.end.row;
8172 };
8173
8174 this.walk = function(callback, endRow, endColumn) {
8175 var lastEnd = 0,
8176 folds = this.folds,
8177 fold,
8178 cmp, stop, isNewRow = true;
8179
8180 if (endRow == null) {
8181 endRow = this.end.row;
8182 endColumn = this.end.column;
8183 }
8184
8185 for (var i = 0; i < folds.length; i++) {
8186 fold = folds[i];
8187
8188 cmp = fold.range.compareStart(endRow, endColumn);
8189 if (cmp == -1) {
8190 callback(null, endRow, endColumn, lastEnd, isNewRow);
8191 return;
8192 }
8193
8194 stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
8195 stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
8196 if (stop || cmp === 0) {
8197 return;
8198 }
8199 isNewRow = !fold.sameRow;
8200 lastEnd = fold.end.column;
8201 }
8202 callback(null, endRow, endColumn, lastEnd, isNewRow);
8203 };
8204
8205 this.getNextFoldTo = function(row, column) {
8206 var fold, cmp;
8207 for (var i = 0; i < this.folds.length; i++) {
8208 fold = this.folds[i];
8209 cmp = fold.range.compareEnd(row, column);
8210 if (cmp == -1) {
8211 return {
8212 fold: fold,
8213 kind: "after"
8214 };
8215 } else if (cmp === 0) {
8216 return {
8217 fold: fold,
8218 kind: "inside"
8219 };
8220 }
8221 }
8222 return null;
8223 };
8224
8225 this.addRemoveChars = function(row, column, len) {
8226 var ret = this.getNextFoldTo(row, column),
8227 fold, folds;
8228 if (ret) {
8229 fold = ret.fold;
8230 if (ret.kind == "inside"
8231 && fold.start.column != column
8232 && fold.start.row != row)
8233 {
8234 window.console && window.console.log(row, column, fold);
8235 } else if (fold.start.row == row) {
8236 folds = this.folds;
8237 var i = folds.indexOf(fold);
8238 if (i === 0) {
8239 this.start.column += len;
8240 }
8241 for (i; i < folds.length; i++) {
8242 fold = folds[i];
8243 fold.start.column += len;
8244 if (!fold.sameRow) {
8245 return;
8246 }
8247 fold.end.column += len;
8248 }
8249 this.end.column += len;
8250 }
8251 }
8252 };
8253
8254 this.split = function(row, column) {
8255 var pos = this.getNextFoldTo(row, column);
8256
8257 if (!pos || pos.kind == "inside")
8258 return null;
8259
8260 var fold = pos.fold;
8261 var folds = this.folds;
8262 var foldData = this.foldData;
8263
8264 var i = folds.indexOf(fold);
8265 var foldBefore = folds[i - 1];
8266 this.end.row = foldBefore.end.row;
8267 this.end.column = foldBefore.end.column;
8268 folds = folds.splice(i, folds.length - i);
8269
8270 var newFoldLine = new FoldLine(foldData, folds);
8271 foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
8272 return newFoldLine;
8273 };
8274
8275 this.merge = function(foldLineNext) {
8276 var folds = foldLineNext.folds;
8277 for (var i = 0; i < folds.length; i++) {
8278 this.addFold(folds[i]);
8279 }
8280 var foldData = this.foldData;
8281 foldData.splice(foldData.indexOf(foldLineNext), 1);
8282 };
8283
8284 this.toString = function() {
8285 var ret = [this.range.toString() + ": [" ];
8286
8287 this.folds.forEach(function(fold) {
8288 ret.push(" " + fold.toString());
8289 });
8290 ret.push("]");
8291 return ret.join("\n");
8292 };
8293
8294 this.idxToPosition = function(idx) {
8295 var lastFoldEndColumn = 0;
8296
8297 for (var i = 0; i < this.folds.length; i++) {
8298 var fold = this.folds[i];
8299
8300 idx -= fold.start.column - lastFoldEndColumn;
8301 if (idx < 0) {
8302 return {
8303 row: fold.start.row,
8304 column: fold.start.column + idx
8305 };
8306 }
8307
8308 idx -= fold.placeholder.length;
8309 if (idx < 0) {
8310 return fold.start;
8311 }
8312
8313 lastFoldEndColumn = fold.end.column;
8314 }
8315
8316 return {
8317 row: this.end.row,
8318 column: this.end.column + idx
8319 };
8320 };
8321}).call(FoldLine.prototype);
8322
8323exports.FoldLine = FoldLine;
8324});
8325
8326ace.define("ace/range_list",["require","exports","module","ace/range"], function(acequire, exports, module) {
8327var Range = acequire("./range").Range;
8328var comparePoints = Range.comparePoints;
8329
8330var RangeList = function() {
8331 this.ranges = [];
8332};
8333
8334(function() {
8335 this.comparePoints = comparePoints;
8336
8337 this.pointIndex = function(pos, excludeEdges, startIndex) {
8338 var list = this.ranges;
8339
8340 for (var i = startIndex || 0; i < list.length; i++) {
8341 var range = list[i];
8342 var cmpEnd = comparePoints(pos, range.end);
8343 if (cmpEnd > 0)
8344 continue;
8345 var cmpStart = comparePoints(pos, range.start);
8346 if (cmpEnd === 0)
8347 return excludeEdges && cmpStart !== 0 ? -i-2 : i;
8348 if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
8349 return i;
8350
8351 return -i-1;
8352 }
8353 return -i - 1;
8354 };
8355
8356 this.add = function(range) {
8357 var excludeEdges = !range.isEmpty();
8358 var startIndex = this.pointIndex(range.start, excludeEdges);
8359 if (startIndex < 0)
8360 startIndex = -startIndex - 1;
8361
8362 var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
8363
8364 if (endIndex < 0)
8365 endIndex = -endIndex - 1;
8366 else
8367 endIndex++;
8368 return this.ranges.splice(startIndex, endIndex - startIndex, range);
8369 };
8370
8371 this.addList = function(list) {
8372 var removed = [];
8373 for (var i = list.length; i--; ) {
8374 removed.push.apply(removed, this.add(list[i]));
8375 }
8376 return removed;
8377 };
8378
8379 this.substractPoint = function(pos) {
8380 var i = this.pointIndex(pos);
8381
8382 if (i >= 0)
8383 return this.ranges.splice(i, 1);
8384 };
8385 this.merge = function() {
8386 var removed = [];
8387 var list = this.ranges;
8388
8389 list = list.sort(function(a, b) {
8390 return comparePoints(a.start, b.start);
8391 });
8392
8393 var next = list[0], range;
8394 for (var i = 1; i < list.length; i++) {
8395 range = next;
8396 next = list[i];
8397 var cmp = comparePoints(range.end, next.start);
8398 if (cmp < 0)
8399 continue;
8400
8401 if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
8402 continue;
8403
8404 if (comparePoints(range.end, next.end) < 0) {
8405 range.end.row = next.end.row;
8406 range.end.column = next.end.column;
8407 }
8408
8409 list.splice(i, 1);
8410 removed.push(next);
8411 next = range;
8412 i--;
8413 }
8414
8415 this.ranges = list;
8416
8417 return removed;
8418 };
8419
8420 this.contains = function(row, column) {
8421 return this.pointIndex({row: row, column: column}) >= 0;
8422 };
8423
8424 this.containsPoint = function(pos) {
8425 return this.pointIndex(pos) >= 0;
8426 };
8427
8428 this.rangeAtPoint = function(pos) {
8429 var i = this.pointIndex(pos);
8430 if (i >= 0)
8431 return this.ranges[i];
8432 };
8433
8434
8435 this.clipRows = function(startRow, endRow) {
8436 var list = this.ranges;
8437 if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)
8438 return [];
8439
8440 var startIndex = this.pointIndex({row: startRow, column: 0});
8441 if (startIndex < 0)
8442 startIndex = -startIndex - 1;
8443 var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);
8444 if (endIndex < 0)
8445 endIndex = -endIndex - 1;
8446
8447 var clipped = [];
8448 for (var i = startIndex; i < endIndex; i++) {
8449 clipped.push(list[i]);
8450 }
8451 return clipped;
8452 };
8453
8454 this.removeAll = function() {
8455 return this.ranges.splice(0, this.ranges.length);
8456 };
8457
8458 this.attach = function(session) {
8459 if (this.session)
8460 this.detach();
8461
8462 this.session = session;
8463 this.onChange = this.$onChange.bind(this);
8464
8465 this.session.on('change', this.onChange);
8466 };
8467
8468 this.detach = function() {
8469 if (!this.session)
8470 return;
8471 this.session.removeListener('change', this.onChange);
8472 this.session = null;
8473 };
8474
8475 this.$onChange = function(delta) {
8476 if (delta.action == "insert"){
8477 var start = delta.start;
8478 var end = delta.end;
8479 } else {
8480 var end = delta.start;
8481 var start = delta.end;
8482 }
8483 var startRow = start.row;
8484 var endRow = end.row;
8485 var lineDif = endRow - startRow;
8486
8487 var colDiff = -start.column + end.column;
8488 var ranges = this.ranges;
8489
8490 for (var i = 0, n = ranges.length; i < n; i++) {
8491 var r = ranges[i];
8492 if (r.end.row < startRow)
8493 continue;
8494 if (r.start.row > startRow)
8495 break;
8496
8497 if (r.start.row == startRow && r.start.column >= start.column ) {
8498 if (r.start.column == start.column && this.$insertRight) ; else {
8499 r.start.column += colDiff;
8500 r.start.row += lineDif;
8501 }
8502 }
8503 if (r.end.row == startRow && r.end.column >= start.column) {
8504 if (r.end.column == start.column && this.$insertRight) {
8505 continue;
8506 }
8507 if (r.end.column == start.column && colDiff > 0 && i < n - 1) {
8508 if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
8509 r.end.column -= colDiff;
8510 }
8511 r.end.column += colDiff;
8512 r.end.row += lineDif;
8513 }
8514 }
8515
8516 if (lineDif != 0 && i < n) {
8517 for (; i < n; i++) {
8518 var r = ranges[i];
8519 r.start.row += lineDif;
8520 r.end.row += lineDif;
8521 }
8522 }
8523 };
8524
8525}).call(RangeList.prototype);
8526
8527exports.RangeList = RangeList;
8528});
8529
8530ace.define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"], function(acequire, exports, module) {
8531
8532acequire("../range").Range;
8533var RangeList = acequire("../range_list").RangeList;
8534var oop = acequire("../lib/oop");
8535var Fold = exports.Fold = function(range, placeholder) {
8536 this.foldLine = null;
8537 this.placeholder = placeholder;
8538 this.range = range;
8539 this.start = range.start;
8540 this.end = range.end;
8541
8542 this.sameRow = range.start.row == range.end.row;
8543 this.subFolds = this.ranges = [];
8544};
8545
8546oop.inherits(Fold, RangeList);
8547
8548(function() {
8549
8550 this.toString = function() {
8551 return '"' + this.placeholder + '" ' + this.range.toString();
8552 };
8553
8554 this.setFoldLine = function(foldLine) {
8555 this.foldLine = foldLine;
8556 this.subFolds.forEach(function(fold) {
8557 fold.setFoldLine(foldLine);
8558 });
8559 };
8560
8561 this.clone = function() {
8562 var range = this.range.clone();
8563 var fold = new Fold(range, this.placeholder);
8564 this.subFolds.forEach(function(subFold) {
8565 fold.subFolds.push(subFold.clone());
8566 });
8567 fold.collapseChildren = this.collapseChildren;
8568 return fold;
8569 };
8570
8571 this.addSubFold = function(fold) {
8572 if (this.range.isEqual(fold))
8573 return;
8574
8575 if (!this.range.containsRange(fold))
8576 throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
8577 consumeRange(fold, this.start);
8578
8579 var row = fold.start.row, column = fold.start.column;
8580 for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
8581 cmp = this.subFolds[i].range.compare(row, column);
8582 if (cmp != 1)
8583 break;
8584 }
8585 var afterStart = this.subFolds[i];
8586
8587 if (cmp == 0)
8588 return afterStart.addSubFold(fold);
8589 var row = fold.range.end.row, column = fold.range.end.column;
8590 for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
8591 cmp = this.subFolds[j].range.compare(row, column);
8592 if (cmp != 1)
8593 break;
8594 }
8595 this.subFolds[j];
8596
8597 if (cmp == 0)
8598 throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
8599
8600 this.subFolds.splice(i, j - i, fold);
8601 fold.setFoldLine(this.foldLine);
8602
8603 return fold;
8604 };
8605
8606 this.restoreRange = function(range) {
8607 return restoreRange(range, this.start);
8608 };
8609
8610}).call(Fold.prototype);
8611
8612function consumePoint(point, anchor) {
8613 point.row -= anchor.row;
8614 if (point.row == 0)
8615 point.column -= anchor.column;
8616}
8617function consumeRange(range, anchor) {
8618 consumePoint(range.start, anchor);
8619 consumePoint(range.end, anchor);
8620}
8621function restorePoint(point, anchor) {
8622 if (point.row == 0)
8623 point.column += anchor.column;
8624 point.row += anchor.row;
8625}
8626function restoreRange(range, anchor) {
8627 restorePoint(range.start, anchor);
8628 restorePoint(range.end, anchor);
8629}
8630
8631});
8632
8633ace.define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"], function(acequire, exports, module) {
8634
8635var Range = acequire("../range").Range;
8636var FoldLine = acequire("./fold_line").FoldLine;
8637var Fold = acequire("./fold").Fold;
8638var TokenIterator = acequire("../token_iterator").TokenIterator;
8639
8640function Folding() {
8641 this.getFoldAt = function(row, column, side) {
8642 var foldLine = this.getFoldLine(row);
8643 if (!foldLine)
8644 return null;
8645
8646 var folds = foldLine.folds;
8647 for (var i = 0; i < folds.length; i++) {
8648 var fold = folds[i];
8649 if (fold.range.contains(row, column)) {
8650 if (side == 1 && fold.range.isEnd(row, column)) {
8651 continue;
8652 } else if (side == -1 && fold.range.isStart(row, column)) {
8653 continue;
8654 }
8655 return fold;
8656 }
8657 }
8658 };
8659 this.getFoldsInRange = function(range) {
8660 var start = range.start;
8661 var end = range.end;
8662 var foldLines = this.$foldData;
8663 var foundFolds = [];
8664
8665 start.column += 1;
8666 end.column -= 1;
8667
8668 for (var i = 0; i < foldLines.length; i++) {
8669 var cmp = foldLines[i].range.compareRange(range);
8670 if (cmp == 2) {
8671 continue;
8672 }
8673 else if (cmp == -2) {
8674 break;
8675 }
8676
8677 var folds = foldLines[i].folds;
8678 for (var j = 0; j < folds.length; j++) {
8679 var fold = folds[j];
8680 cmp = fold.range.compareRange(range);
8681 if (cmp == -2) {
8682 break;
8683 } else if (cmp == 2) {
8684 continue;
8685 } else
8686 if (cmp == 42) {
8687 break;
8688 }
8689 foundFolds.push(fold);
8690 }
8691 }
8692 start.column -= 1;
8693 end.column += 1;
8694
8695 return foundFolds;
8696 };
8697
8698 this.getFoldsInRangeList = function(ranges) {
8699 if (Array.isArray(ranges)) {
8700 var folds = [];
8701 ranges.forEach(function(range) {
8702 folds = folds.concat(this.getFoldsInRange(range));
8703 }, this);
8704 } else {
8705 var folds = this.getFoldsInRange(ranges);
8706 }
8707 return folds;
8708 };
8709 this.getAllFolds = function() {
8710 var folds = [];
8711 var foldLines = this.$foldData;
8712
8713 for (var i = 0; i < foldLines.length; i++)
8714 for (var j = 0; j < foldLines[i].folds.length; j++)
8715 folds.push(foldLines[i].folds[j]);
8716
8717 return folds;
8718 };
8719 this.getFoldStringAt = function(row, column, trim, foldLine) {
8720 foldLine = foldLine || this.getFoldLine(row);
8721 if (!foldLine)
8722 return null;
8723
8724 var lastFold = {
8725 end: { column: 0 }
8726 };
8727 var str, fold;
8728 for (var i = 0; i < foldLine.folds.length; i++) {
8729 fold = foldLine.folds[i];
8730 var cmp = fold.range.compareEnd(row, column);
8731 if (cmp == -1) {
8732 str = this
8733 .getLine(fold.start.row)
8734 .substring(lastFold.end.column, fold.start.column);
8735 break;
8736 }
8737 else if (cmp === 0) {
8738 return null;
8739 }
8740 lastFold = fold;
8741 }
8742 if (!str)
8743 str = this.getLine(fold.start.row).substring(lastFold.end.column);
8744
8745 if (trim == -1)
8746 return str.substring(0, column - lastFold.end.column);
8747 else if (trim == 1)
8748 return str.substring(column - lastFold.end.column);
8749 else
8750 return str;
8751 };
8752
8753 this.getFoldLine = function(docRow, startFoldLine) {
8754 var foldData = this.$foldData;
8755 var i = 0;
8756 if (startFoldLine)
8757 i = foldData.indexOf(startFoldLine);
8758 if (i == -1)
8759 i = 0;
8760 for (i; i < foldData.length; i++) {
8761 var foldLine = foldData[i];
8762 if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
8763 return foldLine;
8764 } else if (foldLine.end.row > docRow) {
8765 return null;
8766 }
8767 }
8768 return null;
8769 };
8770 this.getNextFoldLine = function(docRow, startFoldLine) {
8771 var foldData = this.$foldData;
8772 var i = 0;
8773 if (startFoldLine)
8774 i = foldData.indexOf(startFoldLine);
8775 if (i == -1)
8776 i = 0;
8777 for (i; i < foldData.length; i++) {
8778 var foldLine = foldData[i];
8779 if (foldLine.end.row >= docRow) {
8780 return foldLine;
8781 }
8782 }
8783 return null;
8784 };
8785
8786 this.getFoldedRowCount = function(first, last) {
8787 var foldData = this.$foldData, rowCount = last-first+1;
8788 for (var i = 0; i < foldData.length; i++) {
8789 var foldLine = foldData[i],
8790 end = foldLine.end.row,
8791 start = foldLine.start.row;
8792 if (end >= last) {
8793 if (start < last) {
8794 if (start >= first)
8795 rowCount -= last-start;
8796 else
8797 rowCount = 0; // in one fold
8798 }
8799 break;
8800 } else if (end >= first){
8801 if (start >= first) // fold inside range
8802 rowCount -= end-start;
8803 else
8804 rowCount -= end-first+1;
8805 }
8806 }
8807 return rowCount;
8808 };
8809
8810 this.$addFoldLine = function(foldLine) {
8811 this.$foldData.push(foldLine);
8812 this.$foldData.sort(function(a, b) {
8813 return a.start.row - b.start.row;
8814 });
8815 return foldLine;
8816 };
8817 this.addFold = function(placeholder, range) {
8818 var foldData = this.$foldData;
8819 var added = false;
8820 var fold;
8821
8822 if (placeholder instanceof Fold)
8823 fold = placeholder;
8824 else {
8825 fold = new Fold(range, placeholder);
8826 fold.collapseChildren = range.collapseChildren;
8827 }
8828 this.$clipRangeToDocument(fold.range);
8829
8830 var startRow = fold.start.row;
8831 var startColumn = fold.start.column;
8832 var endRow = fold.end.row;
8833 var endColumn = fold.end.column;
8834 if (!(startRow < endRow ||
8835 startRow == endRow && startColumn <= endColumn - 2))
8836 throw new Error("The range has to be at least 2 characters width");
8837
8838 var startFold = this.getFoldAt(startRow, startColumn, 1);
8839 var endFold = this.getFoldAt(endRow, endColumn, -1);
8840 if (startFold && endFold == startFold)
8841 return startFold.addSubFold(fold);
8842
8843 if (startFold && !startFold.range.isStart(startRow, startColumn))
8844 this.removeFold(startFold);
8845
8846 if (endFold && !endFold.range.isEnd(endRow, endColumn))
8847 this.removeFold(endFold);
8848 var folds = this.getFoldsInRange(fold.range);
8849 if (folds.length > 0) {
8850 this.removeFolds(folds);
8851 folds.forEach(function(subFold) {
8852 fold.addSubFold(subFold);
8853 });
8854 }
8855
8856 for (var i = 0; i < foldData.length; i++) {
8857 var foldLine = foldData[i];
8858 if (endRow == foldLine.start.row) {
8859 foldLine.addFold(fold);
8860 added = true;
8861 break;
8862 } else if (startRow == foldLine.end.row) {
8863 foldLine.addFold(fold);
8864 added = true;
8865 if (!fold.sameRow) {
8866 var foldLineNext = foldData[i + 1];
8867 if (foldLineNext && foldLineNext.start.row == endRow) {
8868 foldLine.merge(foldLineNext);
8869 break;
8870 }
8871 }
8872 break;
8873 } else if (endRow <= foldLine.start.row) {
8874 break;
8875 }
8876 }
8877
8878 if (!added)
8879 foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
8880
8881 if (this.$useWrapMode)
8882 this.$updateWrapData(foldLine.start.row, foldLine.start.row);
8883 else
8884 this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);
8885 this.$modified = true;
8886 this._signal("changeFold", { data: fold, action: "add" });
8887
8888 return fold;
8889 };
8890
8891 this.addFolds = function(folds) {
8892 folds.forEach(function(fold) {
8893 this.addFold(fold);
8894 }, this);
8895 };
8896
8897 this.removeFold = function(fold) {
8898 var foldLine = fold.foldLine;
8899 var startRow = foldLine.start.row;
8900 var endRow = foldLine.end.row;
8901
8902 var foldLines = this.$foldData;
8903 var folds = foldLine.folds;
8904 if (folds.length == 1) {
8905 foldLines.splice(foldLines.indexOf(foldLine), 1);
8906 } else
8907 if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
8908 folds.pop();
8909 foldLine.end.row = folds[folds.length - 1].end.row;
8910 foldLine.end.column = folds[folds.length - 1].end.column;
8911 } else
8912 if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
8913 folds.shift();
8914 foldLine.start.row = folds[0].start.row;
8915 foldLine.start.column = folds[0].start.column;
8916 } else
8917 if (fold.sameRow) {
8918 folds.splice(folds.indexOf(fold), 1);
8919 } else
8920 {
8921 var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
8922 folds = newFoldLine.folds;
8923 folds.shift();
8924 newFoldLine.start.row = folds[0].start.row;
8925 newFoldLine.start.column = folds[0].start.column;
8926 }
8927
8928 if (!this.$updating) {
8929 if (this.$useWrapMode)
8930 this.$updateWrapData(startRow, endRow);
8931 else
8932 this.$updateRowLengthCache(startRow, endRow);
8933 }
8934 this.$modified = true;
8935 this._signal("changeFold", { data: fold, action: "remove" });
8936 };
8937
8938 this.removeFolds = function(folds) {
8939 var cloneFolds = [];
8940 for (var i = 0; i < folds.length; i++) {
8941 cloneFolds.push(folds[i]);
8942 }
8943
8944 cloneFolds.forEach(function(fold) {
8945 this.removeFold(fold);
8946 }, this);
8947 this.$modified = true;
8948 };
8949
8950 this.expandFold = function(fold) {
8951 this.removeFold(fold);
8952 fold.subFolds.forEach(function(subFold) {
8953 fold.restoreRange(subFold);
8954 this.addFold(subFold);
8955 }, this);
8956 if (fold.collapseChildren > 0) {
8957 this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
8958 }
8959 fold.subFolds = [];
8960 };
8961
8962 this.expandFolds = function(folds) {
8963 folds.forEach(function(fold) {
8964 this.expandFold(fold);
8965 }, this);
8966 };
8967
8968 this.unfold = function(location, expandInner) {
8969 var range, folds;
8970 if (location == null) {
8971 range = new Range(0, 0, this.getLength(), 0);
8972 expandInner = true;
8973 } else if (typeof location == "number")
8974 range = new Range(location, 0, location, this.getLine(location).length);
8975 else if ("row" in location)
8976 range = Range.fromPoints(location, location);
8977 else
8978 range = location;
8979
8980 folds = this.getFoldsInRangeList(range);
8981 if (expandInner) {
8982 this.removeFolds(folds);
8983 } else {
8984 var subFolds = folds;
8985 while (subFolds.length) {
8986 this.expandFolds(subFolds);
8987 subFolds = this.getFoldsInRangeList(range);
8988 }
8989 }
8990 if (folds.length)
8991 return folds;
8992 };
8993 this.isRowFolded = function(docRow, startFoldRow) {
8994 return !!this.getFoldLine(docRow, startFoldRow);
8995 };
8996
8997 this.getRowFoldEnd = function(docRow, startFoldRow) {
8998 var foldLine = this.getFoldLine(docRow, startFoldRow);
8999 return foldLine ? foldLine.end.row : docRow;
9000 };
9001
9002 this.getRowFoldStart = function(docRow, startFoldRow) {
9003 var foldLine = this.getFoldLine(docRow, startFoldRow);
9004 return foldLine ? foldLine.start.row : docRow;
9005 };
9006
9007 this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
9008 if (startRow == null)
9009 startRow = foldLine.start.row;
9010 if (startColumn == null)
9011 startColumn = 0;
9012 if (endRow == null)
9013 endRow = foldLine.end.row;
9014 if (endColumn == null)
9015 endColumn = this.getLine(endRow).length;
9016 var doc = this.doc;
9017 var textLine = "";
9018
9019 foldLine.walk(function(placeholder, row, column, lastColumn) {
9020 if (row < startRow)
9021 return;
9022 if (row == startRow) {
9023 if (column < startColumn)
9024 return;
9025 lastColumn = Math.max(startColumn, lastColumn);
9026 }
9027
9028 if (placeholder != null) {
9029 textLine += placeholder;
9030 } else {
9031 textLine += doc.getLine(row).substring(lastColumn, column);
9032 }
9033 }, endRow, endColumn);
9034 return textLine;
9035 };
9036
9037 this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
9038 var foldLine = this.getFoldLine(row);
9039
9040 if (!foldLine) {
9041 var line;
9042 line = this.doc.getLine(row);
9043 return line.substring(startColumn || 0, endColumn || line.length);
9044 } else {
9045 return this.getFoldDisplayLine(
9046 foldLine, row, endColumn, startRow, startColumn);
9047 }
9048 };
9049
9050 this.$cloneFoldData = function() {
9051 var fd = [];
9052 fd = this.$foldData.map(function(foldLine) {
9053 var folds = foldLine.folds.map(function(fold) {
9054 return fold.clone();
9055 });
9056 return new FoldLine(fd, folds);
9057 });
9058
9059 return fd;
9060 };
9061
9062 this.toggleFold = function(tryToUnfold) {
9063 var selection = this.selection;
9064 var range = selection.getRange();
9065 var fold;
9066 var bracketPos;
9067
9068 if (range.isEmpty()) {
9069 var cursor = range.start;
9070 fold = this.getFoldAt(cursor.row, cursor.column);
9071
9072 if (fold) {
9073 this.expandFold(fold);
9074 return;
9075 } else if (bracketPos = this.findMatchingBracket(cursor)) {
9076 if (range.comparePoint(bracketPos) == 1) {
9077 range.end = bracketPos;
9078 } else {
9079 range.start = bracketPos;
9080 range.start.column++;
9081 range.end.column--;
9082 }
9083 } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
9084 if (range.comparePoint(bracketPos) == 1)
9085 range.end = bracketPos;
9086 else
9087 range.start = bracketPos;
9088
9089 range.start.column++;
9090 } else {
9091 range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
9092 }
9093 } else {
9094 var folds = this.getFoldsInRange(range);
9095 if (tryToUnfold && folds.length) {
9096 this.expandFolds(folds);
9097 return;
9098 } else if (folds.length == 1 ) {
9099 fold = folds[0];
9100 }
9101 }
9102
9103 if (!fold)
9104 fold = this.getFoldAt(range.start.row, range.start.column);
9105
9106 if (fold && fold.range.toString() == range.toString()) {
9107 this.expandFold(fold);
9108 return;
9109 }
9110
9111 var placeholder = "...";
9112 if (!range.isMultiLine()) {
9113 placeholder = this.getTextRange(range);
9114 if (placeholder.length < 4)
9115 return;
9116 placeholder = placeholder.trim().substring(0, 2) + "..";
9117 }
9118
9119 this.addFold(placeholder, range);
9120 };
9121
9122 this.getCommentFoldRange = function(row, column, dir) {
9123 var iterator = new TokenIterator(this, row, column);
9124 var token = iterator.getCurrentToken();
9125 var type = token.type;
9126 if (token && /^comment|string/.test(type)) {
9127 type = type.match(/comment|string/)[0];
9128 if (type == "comment")
9129 type += "|doc-start";
9130 var re = new RegExp(type);
9131 var range = new Range();
9132 if (dir != 1) {
9133 do {
9134 token = iterator.stepBackward();
9135 } while (token && re.test(token.type));
9136 iterator.stepForward();
9137 }
9138
9139 range.start.row = iterator.getCurrentTokenRow();
9140 range.start.column = iterator.getCurrentTokenColumn() + 2;
9141
9142 iterator = new TokenIterator(this, row, column);
9143
9144 if (dir != -1) {
9145 var lastRow = -1;
9146 do {
9147 token = iterator.stepForward();
9148 if (lastRow == -1) {
9149 var state = this.getState(iterator.$row);
9150 if (!re.test(state))
9151 lastRow = iterator.$row;
9152 } else if (iterator.$row > lastRow) {
9153 break;
9154 }
9155 } while (token && re.test(token.type));
9156 token = iterator.stepBackward();
9157 } else
9158 token = iterator.getCurrentToken();
9159
9160 range.end.row = iterator.getCurrentTokenRow();
9161 range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
9162 return range;
9163 }
9164 };
9165
9166 this.foldAll = function(startRow, endRow, depth) {
9167 if (depth == undefined)
9168 depth = 100000; // JSON.stringify doesn't hanle Infinity
9169 var foldWidgets = this.foldWidgets;
9170 if (!foldWidgets)
9171 return; // mode doesn't support folding
9172 endRow = endRow || this.getLength();
9173 startRow = startRow || 0;
9174 for (var row = startRow; row < endRow; row++) {
9175 if (foldWidgets[row] == null)
9176 foldWidgets[row] = this.getFoldWidget(row);
9177 if (foldWidgets[row] != "start")
9178 continue;
9179
9180 var range = this.getFoldWidgetRange(row);
9181 if (range && range.isMultiLine()
9182 && range.end.row <= endRow
9183 && range.start.row >= startRow
9184 ) {
9185 row = range.end.row;
9186 try {
9187 var fold = this.addFold("...", range);
9188 if (fold)
9189 fold.collapseChildren = depth;
9190 } catch(e) {}
9191 }
9192 }
9193 };
9194 this.$foldStyles = {
9195 "manual": 1,
9196 "markbegin": 1,
9197 "markbeginend": 1
9198 };
9199 this.$foldStyle = "markbegin";
9200 this.setFoldStyle = function(style) {
9201 if (!this.$foldStyles[style])
9202 throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]");
9203
9204 if (this.$foldStyle == style)
9205 return;
9206
9207 this.$foldStyle = style;
9208
9209 if (style == "manual")
9210 this.unfold();
9211 var mode = this.$foldMode;
9212 this.$setFolding(null);
9213 this.$setFolding(mode);
9214 };
9215
9216 this.$setFolding = function(foldMode) {
9217 if (this.$foldMode == foldMode)
9218 return;
9219
9220 this.$foldMode = foldMode;
9221
9222 this.off('change', this.$updateFoldWidgets);
9223 this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);
9224 this._signal("changeAnnotation");
9225
9226 if (!foldMode || this.$foldStyle == "manual") {
9227 this.foldWidgets = null;
9228 return;
9229 }
9230
9231 this.foldWidgets = [];
9232 this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);
9233 this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);
9234
9235 this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
9236 this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this);
9237 this.on('change', this.$updateFoldWidgets);
9238 this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);
9239 };
9240
9241 this.getParentFoldRangeData = function (row, ignoreCurrent) {
9242 var fw = this.foldWidgets;
9243 if (!fw || (ignoreCurrent && fw[row]))
9244 return {};
9245
9246 var i = row - 1, firstRange;
9247 while (i >= 0) {
9248 var c = fw[i];
9249 if (c == null)
9250 c = fw[i] = this.getFoldWidget(i);
9251
9252 if (c == "start") {
9253 var range = this.getFoldWidgetRange(i);
9254 if (!firstRange)
9255 firstRange = range;
9256 if (range && range.end.row >= row)
9257 break;
9258 }
9259 i--;
9260 }
9261
9262 return {
9263 range: i !== -1 && range,
9264 firstRange: firstRange
9265 };
9266 };
9267
9268 this.onFoldWidgetClick = function(row, e) {
9269 e = e.domEvent;
9270 var options = {
9271 children: e.shiftKey,
9272 all: e.ctrlKey || e.metaKey,
9273 siblings: e.altKey
9274 };
9275
9276 var range = this.$toggleFoldWidget(row, options);
9277 if (!range) {
9278 var el = (e.target || e.srcElement);
9279 if (el && /ace_fold-widget/.test(el.className))
9280 el.className += " ace_invalid";
9281 }
9282 };
9283
9284 this.$toggleFoldWidget = function(row, options) {
9285 if (!this.getFoldWidget)
9286 return;
9287 var type = this.getFoldWidget(row);
9288 var line = this.getLine(row);
9289
9290 var dir = type === "end" ? -1 : 1;
9291 var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
9292
9293 if (fold) {
9294 if (options.children || options.all)
9295 this.removeFold(fold);
9296 else
9297 this.expandFold(fold);
9298 return fold;
9299 }
9300
9301 var range = this.getFoldWidgetRange(row, true);
9302 if (range && !range.isMultiLine()) {
9303 fold = this.getFoldAt(range.start.row, range.start.column, 1);
9304 if (fold && range.isEqual(fold.range)) {
9305 this.removeFold(fold);
9306 return fold;
9307 }
9308 }
9309
9310 if (options.siblings) {
9311 var data = this.getParentFoldRangeData(row);
9312 if (data.range) {
9313 var startRow = data.range.start.row + 1;
9314 var endRow = data.range.end.row;
9315 }
9316 this.foldAll(startRow, endRow, options.all ? 10000 : 0);
9317 } else if (options.children) {
9318 endRow = range ? range.end.row : this.getLength();
9319 this.foldAll(row + 1, endRow, options.all ? 10000 : 0);
9320 } else if (range) {
9321 if (options.all)
9322 range.collapseChildren = 10000;
9323 this.addFold("...", range);
9324 }
9325
9326 return range;
9327 };
9328
9329
9330
9331 this.toggleFoldWidget = function(toggleParent) {
9332 var row = this.selection.getCursor().row;
9333 row = this.getRowFoldStart(row);
9334 var range = this.$toggleFoldWidget(row, {});
9335
9336 if (range)
9337 return;
9338 var data = this.getParentFoldRangeData(row, true);
9339 range = data.range || data.firstRange;
9340
9341 if (range) {
9342 row = range.start.row;
9343 var fold = this.getFoldAt(row, this.getLine(row).length, 1);
9344
9345 if (fold) {
9346 this.removeFold(fold);
9347 } else {
9348 this.addFold("...", range);
9349 }
9350 }
9351 };
9352
9353 this.updateFoldWidgets = function(delta) {
9354 var firstRow = delta.start.row;
9355 var len = delta.end.row - firstRow;
9356
9357 if (len === 0) {
9358 this.foldWidgets[firstRow] = null;
9359 } else if (delta.action == 'remove') {
9360 this.foldWidgets.splice(firstRow, len + 1, null);
9361 } else {
9362 var args = Array(len + 1);
9363 args.unshift(firstRow, 1);
9364 this.foldWidgets.splice.apply(this.foldWidgets, args);
9365 }
9366 };
9367 this.tokenizerUpdateFoldWidgets = function(e) {
9368 var rows = e.data;
9369 if (rows.first != rows.last) {
9370 if (this.foldWidgets.length > rows.first)
9371 this.foldWidgets.splice(rows.first, this.foldWidgets.length);
9372 }
9373 };
9374}
9375
9376exports.Folding = Folding;
9377
9378});
9379
9380ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"], function(acequire, exports, module) {
9381
9382var TokenIterator = acequire("../token_iterator").TokenIterator;
9383var Range = acequire("../range").Range;
9384
9385
9386function BracketMatch() {
9387
9388 this.findMatchingBracket = function(position, chr) {
9389 if (position.column == 0) return null;
9390
9391 var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);
9392 if (charBeforeCursor == "") return null;
9393
9394 var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
9395 if (!match)
9396 return null;
9397
9398 if (match[1])
9399 return this.$findClosingBracket(match[1], position);
9400 else
9401 return this.$findOpeningBracket(match[2], position);
9402 };
9403
9404 this.getBracketRange = function(pos) {
9405 var line = this.getLine(pos.row);
9406 var before = true, range;
9407
9408 var chr = line.charAt(pos.column-1);
9409 var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9410 if (!match) {
9411 chr = line.charAt(pos.column);
9412 pos = {row: pos.row, column: pos.column + 1};
9413 match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9414 before = false;
9415 }
9416 if (!match)
9417 return null;
9418
9419 if (match[1]) {
9420 var bracketPos = this.$findClosingBracket(match[1], pos);
9421 if (!bracketPos)
9422 return null;
9423 range = Range.fromPoints(pos, bracketPos);
9424 if (!before) {
9425 range.end.column++;
9426 range.start.column--;
9427 }
9428 range.cursor = range.end;
9429 } else {
9430 var bracketPos = this.$findOpeningBracket(match[2], pos);
9431 if (!bracketPos)
9432 return null;
9433 range = Range.fromPoints(bracketPos, pos);
9434 if (!before) {
9435 range.start.column++;
9436 range.end.column--;
9437 }
9438 range.cursor = range.start;
9439 }
9440
9441 return range;
9442 };
9443
9444 this.$brackets = {
9445 ")": "(",
9446 "(": ")",
9447 "]": "[",
9448 "[": "]",
9449 "{": "}",
9450 "}": "{"
9451 };
9452
9453 this.$findOpeningBracket = function(bracket, position, typeRe) {
9454 var openBracket = this.$brackets[bracket];
9455 var depth = 1;
9456
9457 var iterator = new TokenIterator(this, position.row, position.column);
9458 var token = iterator.getCurrentToken();
9459 if (!token)
9460 token = iterator.stepForward();
9461 if (!token)
9462 return;
9463
9464 if (!typeRe){
9465 typeRe = new RegExp(
9466 "(\\.?" +
9467 token.type.replace(".", "\\.").replace("rparen", ".paren")
9468 .replace(/\b(?:end)\b/, "(?:start|begin|end)")
9469 + ")+"
9470 );
9471 }
9472 var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
9473 var value = token.value;
9474
9475 while (true) {
9476
9477 while (valueIndex >= 0) {
9478 var chr = value.charAt(valueIndex);
9479 if (chr == openBracket) {
9480 depth -= 1;
9481 if (depth == 0) {
9482 return {row: iterator.getCurrentTokenRow(),
9483 column: valueIndex + iterator.getCurrentTokenColumn()};
9484 }
9485 }
9486 else if (chr == bracket) {
9487 depth += 1;
9488 }
9489 valueIndex -= 1;
9490 }
9491 do {
9492 token = iterator.stepBackward();
9493 } while (token && !typeRe.test(token.type));
9494
9495 if (token == null)
9496 break;
9497
9498 value = token.value;
9499 valueIndex = value.length - 1;
9500 }
9501
9502 return null;
9503 };
9504
9505 this.$findClosingBracket = function(bracket, position, typeRe) {
9506 var closingBracket = this.$brackets[bracket];
9507 var depth = 1;
9508
9509 var iterator = new TokenIterator(this, position.row, position.column);
9510 var token = iterator.getCurrentToken();
9511 if (!token)
9512 token = iterator.stepForward();
9513 if (!token)
9514 return;
9515
9516 if (!typeRe){
9517 typeRe = new RegExp(
9518 "(\\.?" +
9519 token.type.replace(".", "\\.").replace("lparen", ".paren")
9520 .replace(/\b(?:start|begin)\b/, "(?:start|begin|end)")
9521 + ")+"
9522 );
9523 }
9524 var valueIndex = position.column - iterator.getCurrentTokenColumn();
9525
9526 while (true) {
9527
9528 var value = token.value;
9529 var valueLength = value.length;
9530 while (valueIndex < valueLength) {
9531 var chr = value.charAt(valueIndex);
9532 if (chr == closingBracket) {
9533 depth -= 1;
9534 if (depth == 0) {
9535 return {row: iterator.getCurrentTokenRow(),
9536 column: valueIndex + iterator.getCurrentTokenColumn()};
9537 }
9538 }
9539 else if (chr == bracket) {
9540 depth += 1;
9541 }
9542 valueIndex += 1;
9543 }
9544 do {
9545 token = iterator.stepForward();
9546 } while (token && !typeRe.test(token.type));
9547
9548 if (token == null)
9549 break;
9550
9551 valueIndex = 0;
9552 }
9553
9554 return null;
9555 };
9556}
9557exports.BracketMatch = BracketMatch;
9558
9559});
9560
9561ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/bidihandler","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"], function(acequire, exports, module) {
9562
9563var oop = acequire("./lib/oop");
9564var lang = acequire("./lib/lang");
9565var BidiHandler = acequire("./bidihandler").BidiHandler;
9566var config = acequire("./config");
9567var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
9568var Selection = acequire("./selection").Selection;
9569var TextMode = acequire("./mode/text").Mode;
9570var Range = acequire("./range").Range;
9571var Document = acequire("./document").Document;
9572var BackgroundTokenizer = acequire("./background_tokenizer").BackgroundTokenizer;
9573var SearchHighlight = acequire("./search_highlight").SearchHighlight;
9574
9575var EditSession = function(text, mode) {
9576 this.$breakpoints = [];
9577 this.$decorations = [];
9578 this.$frontMarkers = {};
9579 this.$backMarkers = {};
9580 this.$markerId = 1;
9581 this.$undoSelect = true;
9582
9583 this.$foldData = [];
9584 this.id = "session" + (++EditSession.$uid);
9585 this.$foldData.toString = function() {
9586 return this.join("\n");
9587 };
9588 this.on("changeFold", this.onChangeFold.bind(this));
9589 this.$onChange = this.onChange.bind(this);
9590
9591 if (typeof text != "object" || !text.getLine)
9592 text = new Document(text);
9593
9594 this.$bidiHandler = new BidiHandler(this);
9595 this.setDocument(text);
9596 this.selection = new Selection(this);
9597
9598 config.resetOptions(this);
9599 this.setMode(mode);
9600 config._signal("session", this);
9601};
9602
9603
9604EditSession.$uid = 0;
9605
9606(function() {
9607
9608 oop.implement(this, EventEmitter);
9609 this.setDocument = function(doc) {
9610 if (this.doc)
9611 this.doc.removeListener("change", this.$onChange);
9612
9613 this.doc = doc;
9614 doc.on("change", this.$onChange);
9615
9616 if (this.bgTokenizer)
9617 this.bgTokenizer.setDocument(this.getDocument());
9618
9619 this.resetCaches();
9620 };
9621 this.getDocument = function() {
9622 return this.doc;
9623 };
9624 this.$resetRowCache = function(docRow) {
9625 if (!docRow) {
9626 this.$docRowCache = [];
9627 this.$screenRowCache = [];
9628 return;
9629 }
9630 var l = this.$docRowCache.length;
9631 var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;
9632 if (l > i) {
9633 this.$docRowCache.splice(i, l);
9634 this.$screenRowCache.splice(i, l);
9635 }
9636 };
9637
9638 this.$getRowCacheIndex = function(cacheArray, val) {
9639 var low = 0;
9640 var hi = cacheArray.length - 1;
9641
9642 while (low <= hi) {
9643 var mid = (low + hi) >> 1;
9644 var c = cacheArray[mid];
9645
9646 if (val > c)
9647 low = mid + 1;
9648 else if (val < c)
9649 hi = mid - 1;
9650 else
9651 return mid;
9652 }
9653
9654 return low -1;
9655 };
9656
9657 this.resetCaches = function() {
9658 this.$modified = true;
9659 this.$wrapData = [];
9660 this.$rowLengthCache = [];
9661 this.$resetRowCache(0);
9662 if (this.bgTokenizer)
9663 this.bgTokenizer.start(0);
9664 };
9665
9666 this.onChangeFold = function(e) {
9667 var fold = e.data;
9668 this.$resetRowCache(fold.start.row);
9669 };
9670
9671 this.onChange = function(delta) {
9672 this.$modified = true;
9673 this.$bidiHandler.onChange(delta);
9674 this.$resetRowCache(delta.start.row);
9675
9676 var removedFolds = this.$updateInternalDataOnChange(delta);
9677 if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
9678 this.$deltasDoc.push(delta);
9679 if (removedFolds && removedFolds.length != 0) {
9680 this.$deltasFold.push({
9681 action: "removeFolds",
9682 folds: removedFolds
9683 });
9684 }
9685
9686 this.$informUndoManager.schedule();
9687 }
9688
9689 this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta);
9690 this._signal("change", delta);
9691 };
9692 this.setValue = function(text) {
9693 this.doc.setValue(text);
9694 this.selection.moveTo(0, 0);
9695
9696 this.$resetRowCache(0);
9697 this.$deltas = [];
9698 this.$deltasDoc = [];
9699 this.$deltasFold = [];
9700 this.setUndoManager(this.$undoManager);
9701 this.getUndoManager().reset();
9702 };
9703 this.getValue =
9704 this.toString = function() {
9705 return this.doc.getValue();
9706 };
9707 this.getSelection = function() {
9708 return this.selection;
9709 };
9710 this.getState = function(row) {
9711 return this.bgTokenizer.getState(row);
9712 };
9713 this.getTokens = function(row) {
9714 return this.bgTokenizer.getTokens(row);
9715 };
9716 this.getTokenAt = function(row, column) {
9717 var tokens = this.bgTokenizer.getTokens(row);
9718 var token, c = 0;
9719 if (column == null) {
9720 var i = tokens.length - 1;
9721 c = this.getLine(row).length;
9722 } else {
9723 for (var i = 0; i < tokens.length; i++) {
9724 c += tokens[i].value.length;
9725 if (c >= column)
9726 break;
9727 }
9728 }
9729 token = tokens[i];
9730 if (!token)
9731 return null;
9732 token.index = i;
9733 token.start = c - token.value.length;
9734 return token;
9735 };
9736 this.setUndoManager = function(undoManager) {
9737 this.$undoManager = undoManager;
9738 this.$deltas = [];
9739 this.$deltasDoc = [];
9740 this.$deltasFold = [];
9741
9742 if (this.$informUndoManager)
9743 this.$informUndoManager.cancel();
9744
9745 if (undoManager) {
9746 var self = this;
9747
9748 this.$syncInformUndoManager = function() {
9749 self.$informUndoManager.cancel();
9750
9751 if (self.$deltasFold.length) {
9752 self.$deltas.push({
9753 group: "fold",
9754 deltas: self.$deltasFold
9755 });
9756 self.$deltasFold = [];
9757 }
9758
9759 if (self.$deltasDoc.length) {
9760 self.$deltas.push({
9761 group: "doc",
9762 deltas: self.$deltasDoc
9763 });
9764 self.$deltasDoc = [];
9765 }
9766
9767 if (self.$deltas.length > 0) {
9768 undoManager.execute({
9769 action: "aceupdate",
9770 args: [self.$deltas, self],
9771 merge: self.mergeUndoDeltas
9772 });
9773 }
9774 self.mergeUndoDeltas = false;
9775 self.$deltas = [];
9776 };
9777 this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);
9778 }
9779 };
9780 this.markUndoGroup = function() {
9781 if (this.$syncInformUndoManager)
9782 this.$syncInformUndoManager();
9783 };
9784
9785 this.$defaultUndoManager = {
9786 undo: function() {},
9787 redo: function() {},
9788 reset: function() {}
9789 };
9790 this.getUndoManager = function() {
9791 return this.$undoManager || this.$defaultUndoManager;
9792 };
9793 this.getTabString = function() {
9794 if (this.getUseSoftTabs()) {
9795 return lang.stringRepeat(" ", this.getTabSize());
9796 } else {
9797 return "\t";
9798 }
9799 };
9800 this.setUseSoftTabs = function(val) {
9801 this.setOption("useSoftTabs", val);
9802 };
9803 this.getUseSoftTabs = function() {
9804 return this.$useSoftTabs && !this.$mode.$indentWithTabs;
9805 };
9806 this.setTabSize = function(tabSize) {
9807 this.setOption("tabSize", tabSize);
9808 };
9809 this.getTabSize = function() {
9810 return this.$tabSize;
9811 };
9812 this.isTabStop = function(position) {
9813 return this.$useSoftTabs && (position.column % this.$tabSize === 0);
9814 };
9815 this.setNavigateWithinSoftTabs = function (navigateWithinSoftTabs) {
9816 this.setOption("navigateWithinSoftTabs", navigateWithinSoftTabs);
9817 };
9818 this.getNavigateWithinSoftTabs = function() {
9819 return this.$navigateWithinSoftTabs;
9820 };
9821
9822 this.$overwrite = false;
9823 this.setOverwrite = function(overwrite) {
9824 this.setOption("overwrite", overwrite);
9825 };
9826 this.getOverwrite = function() {
9827 return this.$overwrite;
9828 };
9829 this.toggleOverwrite = function() {
9830 this.setOverwrite(!this.$overwrite);
9831 };
9832 this.addGutterDecoration = function(row, className) {
9833 if (!this.$decorations[row])
9834 this.$decorations[row] = "";
9835 this.$decorations[row] += " " + className;
9836 this._signal("changeBreakpoint", {});
9837 };
9838 this.removeGutterDecoration = function(row, className) {
9839 this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
9840 this._signal("changeBreakpoint", {});
9841 };
9842 this.getBreakpoints = function() {
9843 return this.$breakpoints;
9844 };
9845 this.setBreakpoints = function(rows) {
9846 this.$breakpoints = [];
9847 for (var i=0; i<rows.length; i++) {
9848 this.$breakpoints[rows[i]] = "ace_breakpoint";
9849 }
9850 this._signal("changeBreakpoint", {});
9851 };
9852 this.clearBreakpoints = function() {
9853 this.$breakpoints = [];
9854 this._signal("changeBreakpoint", {});
9855 };
9856 this.setBreakpoint = function(row, className) {
9857 if (className === undefined)
9858 className = "ace_breakpoint";
9859 if (className)
9860 this.$breakpoints[row] = className;
9861 else
9862 delete this.$breakpoints[row];
9863 this._signal("changeBreakpoint", {});
9864 };
9865 this.clearBreakpoint = function(row) {
9866 delete this.$breakpoints[row];
9867 this._signal("changeBreakpoint", {});
9868 };
9869 this.addMarker = function(range, clazz, type, inFront) {
9870 var id = this.$markerId++;
9871
9872 var marker = {
9873 range : range,
9874 type : type || "line",
9875 renderer: typeof type == "function" ? type : null,
9876 clazz : clazz,
9877 inFront: !!inFront,
9878 id: id
9879 };
9880
9881 if (inFront) {
9882 this.$frontMarkers[id] = marker;
9883 this._signal("changeFrontMarker");
9884 } else {
9885 this.$backMarkers[id] = marker;
9886 this._signal("changeBackMarker");
9887 }
9888
9889 return id;
9890 };
9891 this.addDynamicMarker = function(marker, inFront) {
9892 if (!marker.update)
9893 return;
9894 var id = this.$markerId++;
9895 marker.id = id;
9896 marker.inFront = !!inFront;
9897
9898 if (inFront) {
9899 this.$frontMarkers[id] = marker;
9900 this._signal("changeFrontMarker");
9901 } else {
9902 this.$backMarkers[id] = marker;
9903 this._signal("changeBackMarker");
9904 }
9905
9906 return marker;
9907 };
9908 this.removeMarker = function(markerId) {
9909 var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
9910 if (!marker)
9911 return;
9912
9913 var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
9914 if (marker) {
9915 delete (markers[markerId]);
9916 this._signal(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
9917 }
9918 };
9919 this.getMarkers = function(inFront) {
9920 return inFront ? this.$frontMarkers : this.$backMarkers;
9921 };
9922
9923 this.highlight = function(re) {
9924 if (!this.$searchHighlight) {
9925 var highlight = new SearchHighlight(null, "ace_selected-word", "text");
9926 this.$searchHighlight = this.addDynamicMarker(highlight);
9927 }
9928 this.$searchHighlight.setRegexp(re);
9929 };
9930 this.highlightLines = function(startRow, endRow, clazz, inFront) {
9931 if (typeof endRow != "number") {
9932 clazz = endRow;
9933 endRow = startRow;
9934 }
9935 if (!clazz)
9936 clazz = "ace_step";
9937
9938 var range = new Range(startRow, 0, endRow, Infinity);
9939 range.id = this.addMarker(range, clazz, "fullLine", inFront);
9940 return range;
9941 };
9942 this.setAnnotations = function(annotations) {
9943 this.$annotations = annotations;
9944 this._signal("changeAnnotation", {});
9945 };
9946 this.getAnnotations = function() {
9947 return this.$annotations || [];
9948 };
9949 this.clearAnnotations = function() {
9950 this.setAnnotations([]);
9951 };
9952 this.$detectNewLine = function(text) {
9953 var match = text.match(/^.*?(\r?\n)/m);
9954 if (match) {
9955 this.$autoNewLine = match[1];
9956 } else {
9957 this.$autoNewLine = "\n";
9958 }
9959 };
9960 this.getWordRange = function(row, column) {
9961 var line = this.getLine(row);
9962
9963 var inToken = false;
9964 if (column > 0)
9965 inToken = !!line.charAt(column - 1).match(this.tokenRe);
9966
9967 if (!inToken)
9968 inToken = !!line.charAt(column).match(this.tokenRe);
9969
9970 if (inToken)
9971 var re = this.tokenRe;
9972 else if (/^\s+$/.test(line.slice(column-1, column+1)))
9973 var re = /\s/;
9974 else
9975 var re = this.nonTokenRe;
9976
9977 var start = column;
9978 if (start > 0) {
9979 do {
9980 start--;
9981 }
9982 while (start >= 0 && line.charAt(start).match(re));
9983 start++;
9984 }
9985
9986 var end = column;
9987 while (end < line.length && line.charAt(end).match(re)) {
9988 end++;
9989 }
9990
9991 return new Range(row, start, row, end);
9992 };
9993 this.getAWordRange = function(row, column) {
9994 var wordRange = this.getWordRange(row, column);
9995 var line = this.getLine(wordRange.end.row);
9996
9997 while (line.charAt(wordRange.end.column).match(/[ \t]/)) {
9998 wordRange.end.column += 1;
9999 }
10000 return wordRange;
10001 };
10002 this.setNewLineMode = function(newLineMode) {
10003 this.doc.setNewLineMode(newLineMode);
10004 };
10005 this.getNewLineMode = function() {
10006 return this.doc.getNewLineMode();
10007 };
10008 this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); };
10009 this.getUseWorker = function() { return this.$useWorker; };
10010 this.onReloadTokenizer = function(e) {
10011 var rows = e.data;
10012 this.bgTokenizer.start(rows.first);
10013 this._signal("tokenizerUpdate", e);
10014 };
10015
10016 this.$modes = {};
10017 this.$mode = null;
10018 this.$modeId = null;
10019 this.setMode = function(mode, cb) {
10020 if (mode && typeof mode === "object") {
10021 if (mode.getTokenizer)
10022 return this.$onChangeMode(mode);
10023 var options = mode;
10024 var path = options.path;
10025 } else {
10026 path = mode || "ace/mode/text";
10027 }
10028 if (!this.$modes["ace/mode/text"])
10029 this.$modes["ace/mode/text"] = new TextMode();
10030
10031 if (this.$modes[path] && !options) {
10032 this.$onChangeMode(this.$modes[path]);
10033 cb && cb();
10034 return;
10035 }
10036 this.$modeId = path;
10037 config.loadModule(["mode", path], function(m) {
10038 if (this.$modeId !== path)
10039 return cb && cb();
10040 if (this.$modes[path] && !options) {
10041 this.$onChangeMode(this.$modes[path]);
10042 } else if (m && m.Mode) {
10043 m = new m.Mode(options);
10044 if (!options) {
10045 this.$modes[path] = m;
10046 m.$id = path;
10047 }
10048 this.$onChangeMode(m);
10049 }
10050 cb && cb();
10051 }.bind(this));
10052 if (!this.$mode)
10053 this.$onChangeMode(this.$modes["ace/mode/text"], true);
10054 };
10055
10056 this.$onChangeMode = function(mode, $isPlaceholder) {
10057 if (!$isPlaceholder)
10058 this.$modeId = mode.$id;
10059 if (this.$mode === mode)
10060 return;
10061
10062 this.$mode = mode;
10063
10064 this.$stopWorker();
10065
10066 if (this.$useWorker)
10067 this.$startWorker();
10068
10069 var tokenizer = mode.getTokenizer();
10070
10071 if(tokenizer.addEventListener !== undefined) {
10072 var onReloadTokenizer = this.onReloadTokenizer.bind(this);
10073 tokenizer.addEventListener("update", onReloadTokenizer);
10074 }
10075
10076 if (!this.bgTokenizer) {
10077 this.bgTokenizer = new BackgroundTokenizer(tokenizer);
10078 var _self = this;
10079 this.bgTokenizer.addEventListener("update", function(e) {
10080 _self._signal("tokenizerUpdate", e);
10081 });
10082 } else {
10083 this.bgTokenizer.setTokenizer(tokenizer);
10084 }
10085
10086 this.bgTokenizer.setDocument(this.getDocument());
10087
10088 this.tokenRe = mode.tokenRe;
10089 this.nonTokenRe = mode.nonTokenRe;
10090
10091
10092 if (!$isPlaceholder) {
10093 if (mode.attachToSession)
10094 mode.attachToSession(this);
10095 this.$options.wrapMethod.set.call(this, this.$wrapMethod);
10096 this.$setFolding(mode.foldingRules);
10097 this.bgTokenizer.start(0);
10098 this._emit("changeMode");
10099 }
10100 };
10101
10102 this.$stopWorker = function() {
10103 if (this.$worker) {
10104 this.$worker.terminate();
10105 this.$worker = null;
10106 }
10107 };
10108
10109 this.$startWorker = function() {
10110 try {
10111 this.$worker = this.$mode.createWorker(this);
10112 } catch (e) {
10113 config.warn("Could not load worker", e);
10114 this.$worker = null;
10115 }
10116 };
10117 this.getMode = function() {
10118 return this.$mode;
10119 };
10120
10121 this.$scrollTop = 0;
10122 this.setScrollTop = function(scrollTop) {
10123 if (this.$scrollTop === scrollTop || isNaN(scrollTop))
10124 return;
10125
10126 this.$scrollTop = scrollTop;
10127 this._signal("changeScrollTop", scrollTop);
10128 };
10129 this.getScrollTop = function() {
10130 return this.$scrollTop;
10131 };
10132
10133 this.$scrollLeft = 0;
10134 this.setScrollLeft = function(scrollLeft) {
10135 if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
10136 return;
10137
10138 this.$scrollLeft = scrollLeft;
10139 this._signal("changeScrollLeft", scrollLeft);
10140 };
10141 this.getScrollLeft = function() {
10142 return this.$scrollLeft;
10143 };
10144 this.getScreenWidth = function() {
10145 this.$computeWidth();
10146 if (this.lineWidgets)
10147 return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);
10148 return this.screenWidth;
10149 };
10150
10151 this.getLineWidgetMaxWidth = function() {
10152 if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth;
10153 var width = 0;
10154 this.lineWidgets.forEach(function(w) {
10155 if (w && w.screenWidth > width)
10156 width = w.screenWidth;
10157 });
10158 return this.lineWidgetWidth = width;
10159 };
10160
10161 this.$computeWidth = function(force) {
10162 if (this.$modified || force) {
10163 this.$modified = false;
10164
10165 if (this.$useWrapMode)
10166 return this.screenWidth = this.$wrapLimit;
10167
10168 var lines = this.doc.getAllLines();
10169 var cache = this.$rowLengthCache;
10170 var longestScreenLine = 0;
10171 var foldIndex = 0;
10172 var foldLine = this.$foldData[foldIndex];
10173 var foldStart = foldLine ? foldLine.start.row : Infinity;
10174 var len = lines.length;
10175
10176 for (var i = 0; i < len; i++) {
10177 if (i > foldStart) {
10178 i = foldLine.end.row + 1;
10179 if (i >= len)
10180 break;
10181 foldLine = this.$foldData[foldIndex++];
10182 foldStart = foldLine ? foldLine.start.row : Infinity;
10183 }
10184
10185 if (cache[i] == null)
10186 cache[i] = this.$getStringScreenWidth(lines[i])[0];
10187
10188 if (cache[i] > longestScreenLine)
10189 longestScreenLine = cache[i];
10190 }
10191 this.screenWidth = longestScreenLine;
10192 }
10193 };
10194 this.getLine = function(row) {
10195 return this.doc.getLine(row);
10196 };
10197 this.getLines = function(firstRow, lastRow) {
10198 return this.doc.getLines(firstRow, lastRow);
10199 };
10200 this.getLength = function() {
10201 return this.doc.getLength();
10202 };
10203 this.getTextRange = function(range) {
10204 return this.doc.getTextRange(range || this.selection.getRange());
10205 };
10206 this.insert = function(position, text) {
10207 return this.doc.insert(position, text);
10208 };
10209 this.remove = function(range) {
10210 return this.doc.remove(range);
10211 };
10212 this.removeFullLines = function(firstRow, lastRow){
10213 return this.doc.removeFullLines(firstRow, lastRow);
10214 };
10215 this.undoChanges = function(deltas, dontSelect) {
10216 if (!deltas.length)
10217 return;
10218
10219 this.$fromUndo = true;
10220 var lastUndoRange = null;
10221 for (var i = deltas.length - 1; i != -1; i--) {
10222 var delta = deltas[i];
10223 if (delta.group == "doc") {
10224 this.doc.revertDeltas(delta.deltas);
10225 lastUndoRange =
10226 this.$getUndoSelection(delta.deltas, true, lastUndoRange);
10227 } else {
10228 delta.deltas.forEach(function(foldDelta) {
10229 this.addFolds(foldDelta.folds);
10230 }, this);
10231 }
10232 }
10233 this.$fromUndo = false;
10234 lastUndoRange &&
10235 this.$undoSelect &&
10236 !dontSelect &&
10237 this.selection.setSelectionRange(lastUndoRange);
10238 return lastUndoRange;
10239 };
10240 this.redoChanges = function(deltas, dontSelect) {
10241 if (!deltas.length)
10242 return;
10243
10244 this.$fromUndo = true;
10245 var lastUndoRange = null;
10246 for (var i = 0; i < deltas.length; i++) {
10247 var delta = deltas[i];
10248 if (delta.group == "doc") {
10249 this.doc.applyDeltas(delta.deltas);
10250 lastUndoRange =
10251 this.$getUndoSelection(delta.deltas, false, lastUndoRange);
10252 }
10253 }
10254 this.$fromUndo = false;
10255 lastUndoRange &&
10256 this.$undoSelect &&
10257 !dontSelect &&
10258 this.selection.setSelectionRange(lastUndoRange);
10259 return lastUndoRange;
10260 };
10261 this.setUndoSelect = function(enable) {
10262 this.$undoSelect = enable;
10263 };
10264
10265 this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
10266 function isInsert(delta) {
10267 return isUndo ? delta.action !== "insert" : delta.action === "insert";
10268 }
10269
10270 var delta = deltas[0];
10271 var range, point;
10272 if (isInsert(delta)) {
10273 range = Range.fromPoints(delta.start, delta.end);
10274 } else {
10275 range = Range.fromPoints(delta.start, delta.start);
10276 }
10277
10278 for (var i = 1; i < deltas.length; i++) {
10279 delta = deltas[i];
10280 if (isInsert(delta)) {
10281 point = delta.start;
10282 if (range.compare(point.row, point.column) == -1) {
10283 range.setStart(point);
10284 }
10285 point = delta.end;
10286 if (range.compare(point.row, point.column) == 1) {
10287 range.setEnd(point);
10288 }
10289 } else {
10290 point = delta.start;
10291 if (range.compare(point.row, point.column) == -1) {
10292 range = Range.fromPoints(delta.start, delta.start);
10293 }
10294 }
10295 }
10296 if (lastUndoRange != null) {
10297 if (Range.comparePoints(lastUndoRange.start, range.start) === 0) {
10298 lastUndoRange.start.column += range.end.column - range.start.column;
10299 lastUndoRange.end.column += range.end.column - range.start.column;
10300 }
10301
10302 var cmp = lastUndoRange.compareRange(range);
10303 if (cmp == 1) {
10304 range.setStart(lastUndoRange.start);
10305 } else if (cmp == -1) {
10306 range.setEnd(lastUndoRange.end);
10307 }
10308 }
10309
10310 return range;
10311 };
10312 this.replace = function(range, text) {
10313 return this.doc.replace(range, text);
10314 };
10315 this.moveText = function(fromRange, toPosition, copy) {
10316 var text = this.getTextRange(fromRange);
10317 var folds = this.getFoldsInRange(fromRange);
10318
10319 var toRange = Range.fromPoints(toPosition, toPosition);
10320 if (!copy) {
10321 this.remove(fromRange);
10322 var rowDiff = fromRange.start.row - fromRange.end.row;
10323 var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
10324 if (collDiff) {
10325 if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
10326 toRange.start.column += collDiff;
10327 if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
10328 toRange.end.column += collDiff;
10329 }
10330 if (rowDiff && toRange.start.row >= fromRange.end.row) {
10331 toRange.start.row += rowDiff;
10332 toRange.end.row += rowDiff;
10333 }
10334 }
10335
10336 toRange.end = this.insert(toRange.start, text);
10337 if (folds.length) {
10338 var oldStart = fromRange.start;
10339 var newStart = toRange.start;
10340 var rowDiff = newStart.row - oldStart.row;
10341 var collDiff = newStart.column - oldStart.column;
10342 this.addFolds(folds.map(function(x) {
10343 x = x.clone();
10344 if (x.start.row == oldStart.row)
10345 x.start.column += collDiff;
10346 if (x.end.row == oldStart.row)
10347 x.end.column += collDiff;
10348 x.start.row += rowDiff;
10349 x.end.row += rowDiff;
10350 return x;
10351 }));
10352 }
10353
10354 return toRange;
10355 };
10356 this.indentRows = function(startRow, endRow, indentString) {
10357 indentString = indentString.replace(/\t/g, this.getTabString());
10358 for (var row=startRow; row<=endRow; row++)
10359 this.doc.insertInLine({row: row, column: 0}, indentString);
10360 };
10361 this.outdentRows = function (range) {
10362 var rowRange = range.collapseRows();
10363 var deleteRange = new Range(0, 0, 0, 0);
10364 var size = this.getTabSize();
10365
10366 for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
10367 var line = this.getLine(i);
10368
10369 deleteRange.start.row = i;
10370 deleteRange.end.row = i;
10371 for (var j = 0; j < size; ++j)
10372 if (line.charAt(j) != ' ')
10373 break;
10374 if (j < size && line.charAt(j) == '\t') {
10375 deleteRange.start.column = j;
10376 deleteRange.end.column = j + 1;
10377 } else {
10378 deleteRange.start.column = 0;
10379 deleteRange.end.column = j;
10380 }
10381 this.remove(deleteRange);
10382 }
10383 };
10384
10385 this.$moveLines = function(firstRow, lastRow, dir) {
10386 firstRow = this.getRowFoldStart(firstRow);
10387 lastRow = this.getRowFoldEnd(lastRow);
10388 if (dir < 0) {
10389 var row = this.getRowFoldStart(firstRow + dir);
10390 if (row < 0) return 0;
10391 var diff = row-firstRow;
10392 } else if (dir > 0) {
10393 var row = this.getRowFoldEnd(lastRow + dir);
10394 if (row > this.doc.getLength()-1) return 0;
10395 var diff = row-lastRow;
10396 } else {
10397 firstRow = this.$clipRowToDocument(firstRow);
10398 lastRow = this.$clipRowToDocument(lastRow);
10399 var diff = lastRow - firstRow + 1;
10400 }
10401
10402 var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
10403 var folds = this.getFoldsInRange(range).map(function(x){
10404 x = x.clone();
10405 x.start.row += diff;
10406 x.end.row += diff;
10407 return x;
10408 });
10409
10410 var lines = dir == 0
10411 ? this.doc.getLines(firstRow, lastRow)
10412 : this.doc.removeFullLines(firstRow, lastRow);
10413 this.doc.insertFullLines(firstRow+diff, lines);
10414 folds.length && this.addFolds(folds);
10415 return diff;
10416 };
10417 this.moveLinesUp = function(firstRow, lastRow) {
10418 return this.$moveLines(firstRow, lastRow, -1);
10419 };
10420 this.moveLinesDown = function(firstRow, lastRow) {
10421 return this.$moveLines(firstRow, lastRow, 1);
10422 };
10423 this.duplicateLines = function(firstRow, lastRow) {
10424 return this.$moveLines(firstRow, lastRow, 0);
10425 };
10426
10427
10428 this.$clipRowToDocument = function(row) {
10429 return Math.max(0, Math.min(row, this.doc.getLength()-1));
10430 };
10431
10432 this.$clipColumnToRow = function(row, column) {
10433 if (column < 0)
10434 return 0;
10435 return Math.min(this.doc.getLine(row).length, column);
10436 };
10437
10438
10439 this.$clipPositionToDocument = function(row, column) {
10440 column = Math.max(0, column);
10441
10442 if (row < 0) {
10443 row = 0;
10444 column = 0;
10445 } else {
10446 var len = this.doc.getLength();
10447 if (row >= len) {
10448 row = len - 1;
10449 column = this.doc.getLine(len-1).length;
10450 } else {
10451 column = Math.min(this.doc.getLine(row).length, column);
10452 }
10453 }
10454
10455 return {
10456 row: row,
10457 column: column
10458 };
10459 };
10460
10461 this.$clipRangeToDocument = function(range) {
10462 if (range.start.row < 0) {
10463 range.start.row = 0;
10464 range.start.column = 0;
10465 } else {
10466 range.start.column = this.$clipColumnToRow(
10467 range.start.row,
10468 range.start.column
10469 );
10470 }
10471
10472 var len = this.doc.getLength() - 1;
10473 if (range.end.row > len) {
10474 range.end.row = len;
10475 range.end.column = this.doc.getLine(len).length;
10476 } else {
10477 range.end.column = this.$clipColumnToRow(
10478 range.end.row,
10479 range.end.column
10480 );
10481 }
10482 return range;
10483 };
10484 this.$wrapLimit = 80;
10485 this.$useWrapMode = false;
10486 this.$wrapLimitRange = {
10487 min : null,
10488 max : null
10489 };
10490 this.setUseWrapMode = function(useWrapMode) {
10491 if (useWrapMode != this.$useWrapMode) {
10492 this.$useWrapMode = useWrapMode;
10493 this.$modified = true;
10494 this.$resetRowCache(0);
10495 if (useWrapMode) {
10496 var len = this.getLength();
10497 this.$wrapData = Array(len);
10498 this.$updateWrapData(0, len - 1);
10499 }
10500
10501 this._signal("changeWrapMode");
10502 }
10503 };
10504 this.getUseWrapMode = function() {
10505 return this.$useWrapMode;
10506 };
10507 this.setWrapLimitRange = function(min, max) {
10508 if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
10509 this.$wrapLimitRange = { min: min, max: max };
10510 this.$modified = true;
10511 this.$bidiHandler.markAsDirty();
10512 if (this.$useWrapMode)
10513 this._signal("changeWrapMode");
10514 }
10515 };
10516 this.adjustWrapLimit = function(desiredLimit, $printMargin) {
10517 var limits = this.$wrapLimitRange;
10518 if (limits.max < 0)
10519 limits = {min: $printMargin, max: $printMargin};
10520 var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max);
10521 if (wrapLimit != this.$wrapLimit && wrapLimit > 1) {
10522 this.$wrapLimit = wrapLimit;
10523 this.$modified = true;
10524 if (this.$useWrapMode) {
10525 this.$updateWrapData(0, this.getLength() - 1);
10526 this.$resetRowCache(0);
10527 this._signal("changeWrapLimit");
10528 }
10529 return true;
10530 }
10531 return false;
10532 };
10533
10534 this.$constrainWrapLimit = function(wrapLimit, min, max) {
10535 if (min)
10536 wrapLimit = Math.max(min, wrapLimit);
10537
10538 if (max)
10539 wrapLimit = Math.min(max, wrapLimit);
10540
10541 return wrapLimit;
10542 };
10543 this.getWrapLimit = function() {
10544 return this.$wrapLimit;
10545 };
10546 this.setWrapLimit = function (limit) {
10547 this.setWrapLimitRange(limit, limit);
10548 };
10549 this.getWrapLimitRange = function() {
10550 return {
10551 min : this.$wrapLimitRange.min,
10552 max : this.$wrapLimitRange.max
10553 };
10554 };
10555
10556 this.$updateInternalDataOnChange = function(delta) {
10557 var useWrapMode = this.$useWrapMode;
10558 var action = delta.action;
10559 var start = delta.start;
10560 var end = delta.end;
10561 var firstRow = start.row;
10562 var lastRow = end.row;
10563 var len = lastRow - firstRow;
10564 var removedFolds = null;
10565
10566 this.$updating = true;
10567 if (len != 0) {
10568 if (action === "remove") {
10569 this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len);
10570
10571 var foldLines = this.$foldData;
10572 removedFolds = this.getFoldsInRange(delta);
10573 this.removeFolds(removedFolds);
10574
10575 var foldLine = this.getFoldLine(end.row);
10576 var idx = 0;
10577 if (foldLine) {
10578 foldLine.addRemoveChars(end.row, end.column, start.column - end.column);
10579 foldLine.shiftRow(-len);
10580
10581 var foldLineBefore = this.getFoldLine(firstRow);
10582 if (foldLineBefore && foldLineBefore !== foldLine) {
10583 foldLineBefore.merge(foldLine);
10584 foldLine = foldLineBefore;
10585 }
10586 idx = foldLines.indexOf(foldLine) + 1;
10587 }
10588
10589 for (idx; idx < foldLines.length; idx++) {
10590 var foldLine = foldLines[idx];
10591 if (foldLine.start.row >= end.row) {
10592 foldLine.shiftRow(-len);
10593 }
10594 }
10595
10596 lastRow = firstRow;
10597 } else {
10598 var args = Array(len);
10599 args.unshift(firstRow, 0);
10600 var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache;
10601 arr.splice.apply(arr, args);
10602 var foldLines = this.$foldData;
10603 var foldLine = this.getFoldLine(firstRow);
10604 var idx = 0;
10605 if (foldLine) {
10606 var cmp = foldLine.range.compareInside(start.row, start.column);
10607 if (cmp == 0) {
10608 foldLine = foldLine.split(start.row, start.column);
10609 if (foldLine) {
10610 foldLine.shiftRow(len);
10611 foldLine.addRemoveChars(lastRow, 0, end.column - start.column);
10612 }
10613 } else
10614 if (cmp == -1) {
10615 foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
10616 foldLine.shiftRow(len);
10617 }
10618 idx = foldLines.indexOf(foldLine) + 1;
10619 }
10620
10621 for (idx; idx < foldLines.length; idx++) {
10622 var foldLine = foldLines[idx];
10623 if (foldLine.start.row >= firstRow) {
10624 foldLine.shiftRow(len);
10625 }
10626 }
10627 }
10628 } else {
10629 len = Math.abs(delta.start.column - delta.end.column);
10630 if (action === "remove") {
10631 removedFolds = this.getFoldsInRange(delta);
10632 this.removeFolds(removedFolds);
10633
10634 len = -len;
10635 }
10636 var foldLine = this.getFoldLine(firstRow);
10637 if (foldLine) {
10638 foldLine.addRemoveChars(firstRow, start.column, len);
10639 }
10640 }
10641
10642 if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {
10643 console.error("doc.getLength() and $wrapData.length have to be the same!");
10644 }
10645 this.$updating = false;
10646
10647 if (useWrapMode)
10648 this.$updateWrapData(firstRow, lastRow);
10649 else
10650 this.$updateRowLengthCache(firstRow, lastRow);
10651
10652 return removedFolds;
10653 };
10654
10655 this.$updateRowLengthCache = function(firstRow, lastRow, b) {
10656 this.$rowLengthCache[firstRow] = null;
10657 this.$rowLengthCache[lastRow] = null;
10658 };
10659
10660 this.$updateWrapData = function(firstRow, lastRow) {
10661 var lines = this.doc.getAllLines();
10662 var tabSize = this.getTabSize();
10663 var wrapData = this.$wrapData;
10664 var wrapLimit = this.$wrapLimit;
10665 var tokens;
10666 var foldLine;
10667
10668 var row = firstRow;
10669 lastRow = Math.min(lastRow, lines.length - 1);
10670 while (row <= lastRow) {
10671 foldLine = this.getFoldLine(row, foldLine);
10672 if (!foldLine) {
10673 tokens = this.$getDisplayTokens(lines[row]);
10674 wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
10675 row ++;
10676 } else {
10677 tokens = [];
10678 foldLine.walk(function(placeholder, row, column, lastColumn) {
10679 var walkTokens;
10680 if (placeholder != null) {
10681 walkTokens = this.$getDisplayTokens(
10682 placeholder, tokens.length);
10683 walkTokens[0] = PLACEHOLDER_START;
10684 for (var i = 1; i < walkTokens.length; i++) {
10685 walkTokens[i] = PLACEHOLDER_BODY;
10686 }
10687 } else {
10688 walkTokens = this.$getDisplayTokens(
10689 lines[row].substring(lastColumn, column),
10690 tokens.length);
10691 }
10692 tokens = tokens.concat(walkTokens);
10693 }.bind(this),
10694 foldLine.end.row,
10695 lines[foldLine.end.row].length + 1
10696 );
10697
10698 wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
10699 row = foldLine.end.row + 1;
10700 }
10701 }
10702 };
10703 var CHAR = 1,
10704 CHAR_EXT = 2,
10705 PLACEHOLDER_START = 3,
10706 PLACEHOLDER_BODY = 4,
10707 PUNCTUATION = 9,
10708 SPACE = 10,
10709 TAB = 11,
10710 TAB_SPACE = 12;
10711
10712
10713 this.$computeWrapSplits = function(tokens, wrapLimit, tabSize) {
10714 if (tokens.length == 0) {
10715 return [];
10716 }
10717
10718 var splits = [];
10719 var displayLength = tokens.length;
10720 var lastSplit = 0, lastDocSplit = 0;
10721
10722 var isCode = this.$wrapAsCode;
10723
10724 var indentedSoftWrap = this.$indentedSoftWrap;
10725 var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8)
10726 || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2);
10727
10728 function getWrapIndent() {
10729 var indentation = 0;
10730 if (maxIndent === 0)
10731 return indentation;
10732 if (indentedSoftWrap) {
10733 for (var i = 0; i < tokens.length; i++) {
10734 var token = tokens[i];
10735 if (token == SPACE)
10736 indentation += 1;
10737 else if (token == TAB)
10738 indentation += tabSize;
10739 else if (token == TAB_SPACE)
10740 continue;
10741 else
10742 break;
10743 }
10744 }
10745 if (isCode && indentedSoftWrap !== false)
10746 indentation += tabSize;
10747 return Math.min(indentation, maxIndent);
10748 }
10749 function addSplit(screenPos) {
10750 var displayed = tokens.slice(lastSplit, screenPos);
10751 var len = displayed.length;
10752 displayed.join("")
10753 .replace(/12/g, function() {
10754 len -= 1;
10755 })
10756 .replace(/2/g, function() {
10757 len -= 1;
10758 });
10759
10760 if (!splits.length) {
10761 indent = getWrapIndent();
10762 splits.indent = indent;
10763 }
10764 lastDocSplit += len;
10765 splits.push(lastDocSplit);
10766 lastSplit = screenPos;
10767 }
10768 var indent = 0;
10769 while (displayLength - lastSplit > wrapLimit - indent) {
10770 var split = lastSplit + wrapLimit - indent;
10771 if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) {
10772 addSplit(split);
10773 continue;
10774 }
10775 if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) {
10776 for (split; split != lastSplit - 1; split--) {
10777 if (tokens[split] == PLACEHOLDER_START) {
10778 break;
10779 }
10780 }
10781 if (split > lastSplit) {
10782 addSplit(split);
10783 continue;
10784 }
10785 split = lastSplit + wrapLimit;
10786 for (split; split < tokens.length; split++) {
10787 if (tokens[split] != PLACEHOLDER_BODY) {
10788 break;
10789 }
10790 }
10791 if (split == tokens.length) {
10792 break; // Breaks the while-loop.
10793 }
10794 addSplit(split);
10795 continue;
10796 }
10797 var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1);
10798 while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
10799 split --;
10800 }
10801 if (isCode) {
10802 while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
10803 split --;
10804 }
10805 while (split > minSplit && tokens[split] == PUNCTUATION) {
10806 split --;
10807 }
10808 } else {
10809 while (split > minSplit && tokens[split] < SPACE) {
10810 split --;
10811 }
10812 }
10813 if (split > minSplit) {
10814 addSplit(++split);
10815 continue;
10816 }
10817 split = lastSplit + wrapLimit;
10818 if (tokens[split] == CHAR_EXT)
10819 split--;
10820 addSplit(split - indent);
10821 }
10822 return splits;
10823 };
10824 this.$getDisplayTokens = function(str, offset) {
10825 var arr = [];
10826 var tabSize;
10827 offset = offset || 0;
10828
10829 for (var i = 0; i < str.length; i++) {
10830 var c = str.charCodeAt(i);
10831 if (c == 9) {
10832 tabSize = this.getScreenTabSize(arr.length + offset);
10833 arr.push(TAB);
10834 for (var n = 1; n < tabSize; n++) {
10835 arr.push(TAB_SPACE);
10836 }
10837 }
10838 else if (c == 32) {
10839 arr.push(SPACE);
10840 } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {
10841 arr.push(PUNCTUATION);
10842 }
10843 else if (c >= 0x1100 && isFullWidth(c)) {
10844 arr.push(CHAR, CHAR_EXT);
10845 } else {
10846 arr.push(CHAR);
10847 }
10848 }
10849 return arr;
10850 };
10851 this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
10852 if (maxScreenColumn == 0)
10853 return [0, 0];
10854 if (maxScreenColumn == null)
10855 maxScreenColumn = Infinity;
10856 screenColumn = screenColumn || 0;
10857
10858 var c, column;
10859 for (column = 0; column < str.length; column++) {
10860 c = str.charCodeAt(column);
10861 if (c == 9) {
10862 screenColumn += this.getScreenTabSize(screenColumn);
10863 }
10864 else if (c >= 0x1100 && isFullWidth(c)) {
10865 screenColumn += 2;
10866 } else {
10867 screenColumn += 1;
10868 }
10869 if (screenColumn > maxScreenColumn) {
10870 break;
10871 }
10872 }
10873
10874 return [screenColumn, column];
10875 };
10876
10877 this.lineWidgets = null;
10878 this.getRowLength = function(row) {
10879 if (this.lineWidgets)
10880 var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
10881 else
10882 h = 0;
10883 if (!this.$useWrapMode || !this.$wrapData[row]) {
10884 return 1 + h;
10885 } else {
10886 return this.$wrapData[row].length + 1 + h;
10887 }
10888 };
10889 this.getRowLineCount = function(row) {
10890 if (!this.$useWrapMode || !this.$wrapData[row]) {
10891 return 1;
10892 } else {
10893 return this.$wrapData[row].length + 1;
10894 }
10895 };
10896
10897 this.getRowWrapIndent = function(screenRow) {
10898 if (this.$useWrapMode) {
10899 var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
10900 var splits = this.$wrapData[pos.row];
10901 return splits.length && splits[0] < pos.column ? splits.indent : 0;
10902 } else {
10903 return 0;
10904 }
10905 };
10906 this.getScreenLastRowColumn = function(screenRow) {
10907 var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
10908 return this.documentToScreenColumn(pos.row, pos.column);
10909 };
10910 this.getDocumentLastRowColumn = function(docRow, docColumn) {
10911 var screenRow = this.documentToScreenRow(docRow, docColumn);
10912 return this.getScreenLastRowColumn(screenRow);
10913 };
10914 this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
10915 var screenRow = this.documentToScreenRow(docRow, docColumn);
10916 return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
10917 };
10918 this.getRowSplitData = function(row) {
10919 if (!this.$useWrapMode) {
10920 return undefined;
10921 } else {
10922 return this.$wrapData[row];
10923 }
10924 };
10925 this.getScreenTabSize = function(screenColumn) {
10926 return this.$tabSize - screenColumn % this.$tabSize;
10927 };
10928
10929
10930 this.screenToDocumentRow = function(screenRow, screenColumn) {
10931 return this.screenToDocumentPosition(screenRow, screenColumn).row;
10932 };
10933
10934
10935 this.screenToDocumentColumn = function(screenRow, screenColumn) {
10936 return this.screenToDocumentPosition(screenRow, screenColumn).column;
10937 };
10938 this.screenToDocumentPosition = function(screenRow, screenColumn, offsetX) {
10939 if (screenRow < 0)
10940 return {row: 0, column: 0};
10941
10942 var line;
10943 var docRow = 0;
10944 var docColumn = 0;
10945 var column;
10946 var row = 0;
10947 var rowLength = 0;
10948
10949 var rowCache = this.$screenRowCache;
10950 var i = this.$getRowCacheIndex(rowCache, screenRow);
10951 var l = rowCache.length;
10952 if (l && i >= 0) {
10953 var row = rowCache[i];
10954 var docRow = this.$docRowCache[i];
10955 var doCache = screenRow > rowCache[l - 1];
10956 } else {
10957 var doCache = !l;
10958 }
10959
10960 var maxRow = this.getLength() - 1;
10961 var foldLine = this.getNextFoldLine(docRow);
10962 var foldStart = foldLine ? foldLine.start.row : Infinity;
10963
10964 while (row <= screenRow) {
10965 rowLength = this.getRowLength(docRow);
10966 if (row + rowLength > screenRow || docRow >= maxRow) {
10967 break;
10968 } else {
10969 row += rowLength;
10970 docRow++;
10971 if (docRow > foldStart) {
10972 docRow = foldLine.end.row+1;
10973 foldLine = this.getNextFoldLine(docRow, foldLine);
10974 foldStart = foldLine ? foldLine.start.row : Infinity;
10975 }
10976 }
10977
10978 if (doCache) {
10979 this.$docRowCache.push(docRow);
10980 this.$screenRowCache.push(row);
10981 }
10982 }
10983
10984 if (foldLine && foldLine.start.row <= docRow) {
10985 line = this.getFoldDisplayLine(foldLine);
10986 docRow = foldLine.start.row;
10987 } else if (row + rowLength <= screenRow || docRow > maxRow) {
10988 return {
10989 row: maxRow,
10990 column: this.getLine(maxRow).length
10991 };
10992 } else {
10993 line = this.getLine(docRow);
10994 foldLine = null;
10995 }
10996 var wrapIndent = 0, splitIndex = Math.floor(screenRow - row);
10997 if (this.$useWrapMode) {
10998 var splits = this.$wrapData[docRow];
10999 if (splits) {
11000 column = splits[splitIndex];
11001 if(splitIndex > 0 && splits.length) {
11002 wrapIndent = splits.indent;
11003 docColumn = splits[splitIndex - 1] || splits[splits.length - 1];
11004 line = line.substring(docColumn);
11005 }
11006 }
11007 }
11008
11009 if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex))
11010 screenColumn = this.$bidiHandler.offsetToCol(offsetX);
11011
11012 docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1];
11013 if (this.$useWrapMode && docColumn >= column)
11014 docColumn = column - 1;
11015
11016 if (foldLine)
11017 return foldLine.idxToPosition(docColumn);
11018
11019 return {row: docRow, column: docColumn};
11020 };
11021 this.documentToScreenPosition = function(docRow, docColumn) {
11022 if (typeof docColumn === "undefined")
11023 var pos = this.$clipPositionToDocument(docRow.row, docRow.column);
11024 else
11025 pos = this.$clipPositionToDocument(docRow, docColumn);
11026
11027 docRow = pos.row;
11028 docColumn = pos.column;
11029
11030 var screenRow = 0;
11031 var foldStartRow = null;
11032 var fold = null;
11033 fold = this.getFoldAt(docRow, docColumn, 1);
11034 if (fold) {
11035 docRow = fold.start.row;
11036 docColumn = fold.start.column;
11037 }
11038
11039 var rowEnd, row = 0;
11040
11041
11042 var rowCache = this.$docRowCache;
11043 var i = this.$getRowCacheIndex(rowCache, docRow);
11044 var l = rowCache.length;
11045 if (l && i >= 0) {
11046 var row = rowCache[i];
11047 var screenRow = this.$screenRowCache[i];
11048 var doCache = docRow > rowCache[l - 1];
11049 } else {
11050 var doCache = !l;
11051 }
11052
11053 var foldLine = this.getNextFoldLine(row);
11054 var foldStart = foldLine ?foldLine.start.row :Infinity;
11055
11056 while (row < docRow) {
11057 if (row >= foldStart) {
11058 rowEnd = foldLine.end.row + 1;
11059 if (rowEnd > docRow)
11060 break;
11061 foldLine = this.getNextFoldLine(rowEnd, foldLine);
11062 foldStart = foldLine ?foldLine.start.row :Infinity;
11063 }
11064 else {
11065 rowEnd = row + 1;
11066 }
11067
11068 screenRow += this.getRowLength(row);
11069 row = rowEnd;
11070
11071 if (doCache) {
11072 this.$docRowCache.push(row);
11073 this.$screenRowCache.push(screenRow);
11074 }
11075 }
11076 var textLine = "";
11077 if (foldLine && row >= foldStart) {
11078 textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
11079 foldStartRow = foldLine.start.row;
11080 } else {
11081 textLine = this.getLine(docRow).substring(0, docColumn);
11082 foldStartRow = docRow;
11083 }
11084 var wrapIndent = 0;
11085 if (this.$useWrapMode) {
11086 var wrapRow = this.$wrapData[foldStartRow];
11087 if (wrapRow) {
11088 var screenRowOffset = 0;
11089 while (textLine.length >= wrapRow[screenRowOffset]) {
11090 screenRow ++;
11091 screenRowOffset++;
11092 }
11093 textLine = textLine.substring(
11094 wrapRow[screenRowOffset - 1] || 0, textLine.length
11095 );
11096 wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;
11097 }
11098 }
11099
11100 return {
11101 row: screenRow,
11102 column: wrapIndent + this.$getStringScreenWidth(textLine)[0]
11103 };
11104 };
11105 this.documentToScreenColumn = function(row, docColumn) {
11106 return this.documentToScreenPosition(row, docColumn).column;
11107 };
11108 this.documentToScreenRow = function(docRow, docColumn) {
11109 return this.documentToScreenPosition(docRow, docColumn).row;
11110 };
11111 this.getScreenLength = function() {
11112 var screenRows = 0;
11113 var fold = null;
11114 if (!this.$useWrapMode) {
11115 screenRows = this.getLength();
11116 var foldData = this.$foldData;
11117 for (var i = 0; i < foldData.length; i++) {
11118 fold = foldData[i];
11119 screenRows -= fold.end.row - fold.start.row;
11120 }
11121 } else {
11122 var lastRow = this.$wrapData.length;
11123 var row = 0, i = 0;
11124 var fold = this.$foldData[i++];
11125 var foldStart = fold ? fold.start.row :Infinity;
11126
11127 while (row < lastRow) {
11128 var splits = this.$wrapData[row];
11129 screenRows += splits ? splits.length + 1 : 1;
11130 row ++;
11131 if (row > foldStart) {
11132 row = fold.end.row+1;
11133 fold = this.$foldData[i++];
11134 foldStart = fold ?fold.start.row :Infinity;
11135 }
11136 }
11137 }
11138 if (this.lineWidgets)
11139 screenRows += this.$getWidgetScreenLength();
11140
11141 return screenRows;
11142 };
11143 this.$setFontMetrics = function(fm) {
11144 if (!this.$enableVarChar) return;
11145 this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
11146 if (maxScreenColumn === 0)
11147 return [0, 0];
11148 if (!maxScreenColumn)
11149 maxScreenColumn = Infinity;
11150 screenColumn = screenColumn || 0;
11151
11152 var c, column;
11153 for (column = 0; column < str.length; column++) {
11154 c = str.charAt(column);
11155 if (c === "\t") {
11156 screenColumn += this.getScreenTabSize(screenColumn);
11157 } else {
11158 screenColumn += fm.getCharacterWidth(c);
11159 }
11160 if (screenColumn > maxScreenColumn) {
11161 break;
11162 }
11163 }
11164
11165 return [screenColumn, column];
11166 };
11167 };
11168
11169 this.destroy = function() {
11170 if (this.bgTokenizer) {
11171 this.bgTokenizer.setDocument(null);
11172 this.bgTokenizer = null;
11173 }
11174 this.$stopWorker();
11175 };
11176
11177 this.isFullWidth = isFullWidth;
11178 function isFullWidth(c) {
11179 if (c < 0x1100)
11180 return false;
11181 return c >= 0x1100 && c <= 0x115F ||
11182 c >= 0x11A3 && c <= 0x11A7 ||
11183 c >= 0x11FA && c <= 0x11FF ||
11184 c >= 0x2329 && c <= 0x232A ||
11185 c >= 0x2E80 && c <= 0x2E99 ||
11186 c >= 0x2E9B && c <= 0x2EF3 ||
11187 c >= 0x2F00 && c <= 0x2FD5 ||
11188 c >= 0x2FF0 && c <= 0x2FFB ||
11189 c >= 0x3000 && c <= 0x303E ||
11190 c >= 0x3041 && c <= 0x3096 ||
11191 c >= 0x3099 && c <= 0x30FF ||
11192 c >= 0x3105 && c <= 0x312D ||
11193 c >= 0x3131 && c <= 0x318E ||
11194 c >= 0x3190 && c <= 0x31BA ||
11195 c >= 0x31C0 && c <= 0x31E3 ||
11196 c >= 0x31F0 && c <= 0x321E ||
11197 c >= 0x3220 && c <= 0x3247 ||
11198 c >= 0x3250 && c <= 0x32FE ||
11199 c >= 0x3300 && c <= 0x4DBF ||
11200 c >= 0x4E00 && c <= 0xA48C ||
11201 c >= 0xA490 && c <= 0xA4C6 ||
11202 c >= 0xA960 && c <= 0xA97C ||
11203 c >= 0xAC00 && c <= 0xD7A3 ||
11204 c >= 0xD7B0 && c <= 0xD7C6 ||
11205 c >= 0xD7CB && c <= 0xD7FB ||
11206 c >= 0xF900 && c <= 0xFAFF ||
11207 c >= 0xFE10 && c <= 0xFE19 ||
11208 c >= 0xFE30 && c <= 0xFE52 ||
11209 c >= 0xFE54 && c <= 0xFE66 ||
11210 c >= 0xFE68 && c <= 0xFE6B ||
11211 c >= 0xFF01 && c <= 0xFF60 ||
11212 c >= 0xFFE0 && c <= 0xFFE6;
11213 }
11214
11215}).call(EditSession.prototype);
11216
11217acequire("./edit_session/folding").Folding.call(EditSession.prototype);
11218acequire("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
11219
11220
11221config.defineOptions(EditSession.prototype, "session", {
11222 wrap: {
11223 set: function(value) {
11224 if (!value || value == "off")
11225 value = false;
11226 else if (value == "free")
11227 value = true;
11228 else if (value == "printMargin")
11229 value = -1;
11230 else if (typeof value == "string")
11231 value = parseInt(value, 10) || false;
11232
11233 if (this.$wrap == value)
11234 return;
11235 this.$wrap = value;
11236 if (!value) {
11237 this.setUseWrapMode(false);
11238 } else {
11239 var col = typeof value == "number" ? value : null;
11240 this.setWrapLimitRange(col, col);
11241 this.setUseWrapMode(true);
11242 }
11243 },
11244 get: function() {
11245 if (this.getUseWrapMode()) {
11246 if (this.$wrap == -1)
11247 return "printMargin";
11248 if (!this.getWrapLimitRange().min)
11249 return "free";
11250 return this.$wrap;
11251 }
11252 return "off";
11253 },
11254 handlesSet: true
11255 },
11256 wrapMethod: {
11257 set: function(val) {
11258 val = val == "auto"
11259 ? this.$mode.type != "text"
11260 : val != "text";
11261 if (val != this.$wrapAsCode) {
11262 this.$wrapAsCode = val;
11263 if (this.$useWrapMode) {
11264 this.$modified = true;
11265 this.$resetRowCache(0);
11266 this.$updateWrapData(0, this.getLength() - 1);
11267 }
11268 }
11269 },
11270 initialValue: "auto"
11271 },
11272 indentedSoftWrap: { initialValue: true },
11273 firstLineNumber: {
11274 set: function() {this._signal("changeBreakpoint");},
11275 initialValue: 1
11276 },
11277 useWorker: {
11278 set: function(useWorker) {
11279 this.$useWorker = useWorker;
11280
11281 this.$stopWorker();
11282 if (useWorker)
11283 this.$startWorker();
11284 },
11285 initialValue: true
11286 },
11287 useSoftTabs: {initialValue: true},
11288 tabSize: {
11289 set: function(tabSize) {
11290 if (isNaN(tabSize) || this.$tabSize === tabSize) return;
11291
11292 this.$modified = true;
11293 this.$rowLengthCache = [];
11294 this.$tabSize = tabSize;
11295 this._signal("changeTabSize");
11296 },
11297 initialValue: 4,
11298 handlesSet: true
11299 },
11300 navigateWithinSoftTabs: {initialValue: false},
11301 overwrite: {
11302 set: function(val) {this._signal("changeOverwrite");},
11303 initialValue: false
11304 },
11305 newLineMode: {
11306 set: function(val) {this.doc.setNewLineMode(val);},
11307 get: function() {return this.doc.getNewLineMode();},
11308 handlesSet: true
11309 },
11310 mode: {
11311 set: function(val) { this.setMode(val); },
11312 get: function() { return this.$modeId; }
11313 }
11314});
11315
11316exports.EditSession = EditSession;
11317});
11318
11319ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(acequire, exports, module) {
11320
11321var lang = acequire("./lib/lang");
11322var oop = acequire("./lib/oop");
11323var Range = acequire("./range").Range;
11324
11325var Search = function() {
11326 this.$options = {};
11327};
11328
11329(function() {
11330 this.set = function(options) {
11331 oop.mixin(this.$options, options);
11332 return this;
11333 };
11334 this.getOptions = function() {
11335 return lang.copyObject(this.$options);
11336 };
11337 this.setOptions = function(options) {
11338 this.$options = options;
11339 };
11340 this.find = function(session) {
11341 var options = this.$options;
11342 var iterator = this.$matchIterator(session, options);
11343 if (!iterator)
11344 return false;
11345
11346 var firstRange = null;
11347 iterator.forEach(function(sr, sc, er, ec) {
11348 firstRange = new Range(sr, sc, er, ec);
11349 if (sc == ec && options.start && options.start.start
11350 && options.skipCurrent != false && firstRange.isEqual(options.start)
11351 ) {
11352 firstRange = null;
11353 return false;
11354 }
11355
11356 return true;
11357 });
11358
11359 return firstRange;
11360 };
11361 this.findAll = function(session) {
11362 var options = this.$options;
11363 if (!options.needle)
11364 return [];
11365 this.$assembleRegExp(options);
11366
11367 var range = options.range;
11368 var lines = range
11369 ? session.getLines(range.start.row, range.end.row)
11370 : session.doc.getAllLines();
11371
11372 var ranges = [];
11373 var re = options.re;
11374 if (options.$isMultiLine) {
11375 var len = re.length;
11376 var maxRow = lines.length - len;
11377 var prevRange;
11378 outer: for (var row = re.offset || 0; row <= maxRow; row++) {
11379 for (var j = 0; j < len; j++)
11380 if (lines[row + j].search(re[j]) == -1)
11381 continue outer;
11382
11383 var startLine = lines[row];
11384 var line = lines[row + len - 1];
11385 var startIndex = startLine.length - startLine.match(re[0])[0].length;
11386 var endIndex = line.match(re[len - 1])[0].length;
11387
11388 if (prevRange && prevRange.end.row === row &&
11389 prevRange.end.column > startIndex
11390 ) {
11391 continue;
11392 }
11393 ranges.push(prevRange = new Range(
11394 row, startIndex, row + len - 1, endIndex
11395 ));
11396 if (len > 2)
11397 row = row + len - 2;
11398 }
11399 } else {
11400 for (var i = 0; i < lines.length; i++) {
11401 var matches = lang.getMatchOffsets(lines[i], re);
11402 for (var j = 0; j < matches.length; j++) {
11403 var match = matches[j];
11404 ranges.push(new Range(i, match.offset, i, match.offset + match.length));
11405 }
11406 }
11407 }
11408
11409 if (range) {
11410 var startColumn = range.start.column;
11411 var endColumn = range.start.column;
11412 var i = 0, j = ranges.length - 1;
11413 while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)
11414 i++;
11415
11416 while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)
11417 j--;
11418
11419 ranges = ranges.slice(i, j + 1);
11420 for (i = 0, j = ranges.length; i < j; i++) {
11421 ranges[i].start.row += range.start.row;
11422 ranges[i].end.row += range.start.row;
11423 }
11424 }
11425
11426 return ranges;
11427 };
11428 this.replace = function(input, replacement) {
11429 var options = this.$options;
11430
11431 var re = this.$assembleRegExp(options);
11432 if (options.$isMultiLine)
11433 return replacement;
11434
11435 if (!re)
11436 return;
11437
11438 var match = re.exec(input);
11439 if (!match || match[0].length != input.length)
11440 return null;
11441
11442 replacement = input.replace(re, replacement);
11443 if (options.preserveCase) {
11444 replacement = replacement.split("");
11445 for (var i = Math.min(input.length, input.length); i--; ) {
11446 var ch = input[i];
11447 if (ch && ch.toLowerCase() != ch)
11448 replacement[i] = replacement[i].toUpperCase();
11449 else
11450 replacement[i] = replacement[i].toLowerCase();
11451 }
11452 replacement = replacement.join("");
11453 }
11454
11455 return replacement;
11456 };
11457
11458 this.$assembleRegExp = function(options, $disableFakeMultiline) {
11459 if (options.needle instanceof RegExp)
11460 return options.re = options.needle;
11461
11462 var needle = options.needle;
11463
11464 if (!options.needle)
11465 return options.re = false;
11466
11467 if (!options.regExp)
11468 needle = lang.escapeRegExp(needle);
11469
11470 if (options.wholeWord)
11471 needle = addWordBoundary(needle, options);
11472
11473 var modifier = options.caseSensitive ? "gm" : "gmi";
11474
11475 options.$isMultiLine = !$disableFakeMultiline && /[\n\r]/.test(needle);
11476 if (options.$isMultiLine)
11477 return options.re = this.$assembleMultilineRegExp(needle, modifier);
11478
11479 try {
11480 var re = new RegExp(needle, modifier);
11481 } catch(e) {
11482 re = false;
11483 }
11484 return options.re = re;
11485 };
11486
11487 this.$assembleMultilineRegExp = function(needle, modifier) {
11488 var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n");
11489 var re = [];
11490 for (var i = 0; i < parts.length; i++) try {
11491 re.push(new RegExp(parts[i], modifier));
11492 } catch(e) {
11493 return false;
11494 }
11495 return re;
11496 };
11497
11498 this.$matchIterator = function(session, options) {
11499 var re = this.$assembleRegExp(options);
11500 if (!re)
11501 return false;
11502 var backwards = options.backwards == true;
11503 var skipCurrent = options.skipCurrent != false;
11504
11505 var range = options.range;
11506 var start = options.start;
11507 if (!start)
11508 start = range ? range[backwards ? "end" : "start"] : session.selection.getRange();
11509
11510 if (start.start)
11511 start = start[skipCurrent != backwards ? "end" : "start"];
11512
11513 var firstRow = range ? range.start.row : 0;
11514 var lastRow = range ? range.end.row : session.getLength() - 1;
11515
11516 if (backwards) {
11517 var forEach = function(callback) {
11518 var row = start.row;
11519 if (forEachInLine(row, start.column, callback))
11520 return;
11521 for (row--; row >= firstRow; row--)
11522 if (forEachInLine(row, Number.MAX_VALUE, callback))
11523 return;
11524 if (options.wrap == false)
11525 return;
11526 for (row = lastRow, firstRow = start.row; row >= firstRow; row--)
11527 if (forEachInLine(row, Number.MAX_VALUE, callback))
11528 return;
11529 };
11530 }
11531 else {
11532 var forEach = function(callback) {
11533 var row = start.row;
11534 if (forEachInLine(row, start.column, callback))
11535 return;
11536 for (row = row + 1; row <= lastRow; row++)
11537 if (forEachInLine(row, 0, callback))
11538 return;
11539 if (options.wrap == false)
11540 return;
11541 for (row = firstRow, lastRow = start.row; row <= lastRow; row++)
11542 if (forEachInLine(row, 0, callback))
11543 return;
11544 };
11545 }
11546
11547 if (options.$isMultiLine) {
11548 var len = re.length;
11549 var forEachInLine = function(row, offset, callback) {
11550 var startRow = backwards ? row - len + 1 : row;
11551 if (startRow < 0) return;
11552 var line = session.getLine(startRow);
11553 var startIndex = line.search(re[0]);
11554 if (!backwards && startIndex < offset || startIndex === -1) return;
11555 for (var i = 1; i < len; i++) {
11556 line = session.getLine(startRow + i);
11557 if (line.search(re[i]) == -1)
11558 return;
11559 }
11560 var endIndex = line.match(re[len - 1])[0].length;
11561 if (backwards && endIndex > offset) return;
11562 if (callback(startRow, startIndex, startRow + len - 1, endIndex))
11563 return true;
11564 };
11565 }
11566 else if (backwards) {
11567 var forEachInLine = function(row, endIndex, callback) {
11568 var line = session.getLine(row);
11569 var matches = [];
11570 var m, last = 0;
11571 re.lastIndex = 0;
11572 while((m = re.exec(line))) {
11573 var length = m[0].length;
11574 last = m.index;
11575 if (!length) {
11576 if (last >= line.length) break;
11577 re.lastIndex = last += 1;
11578 }
11579 if (m.index + length > endIndex)
11580 break;
11581 matches.push(m.index, length);
11582 }
11583 for (var i = matches.length - 1; i >= 0; i -= 2) {
11584 var column = matches[i - 1];
11585 var length = matches[i];
11586 if (callback(row, column, row, column + length))
11587 return true;
11588 }
11589 };
11590 }
11591 else {
11592 var forEachInLine = function(row, startIndex, callback) {
11593 var line = session.getLine(row);
11594 var m;
11595 var last = startIndex;
11596 re.lastIndex = startIndex;
11597 while((m = re.exec(line))) {
11598 var length = m[0].length;
11599 last = m.index;
11600 if (callback(row, last, row,last + length))
11601 return true;
11602 if (!length) {
11603 re.lastIndex = last += 1;
11604 if (last >= line.length) return false;
11605 }
11606 }
11607 };
11608 }
11609 return {forEach: forEach};
11610 };
11611
11612}).call(Search.prototype);
11613
11614function addWordBoundary(needle, options) {
11615 function wordBoundary(c) {
11616 if (/\w/.test(c) || options.regExp) return "\\b";
11617 return "";
11618 }
11619 return wordBoundary(needle[0]) + needle
11620 + wordBoundary(needle[needle.length - 1]);
11621}
11622
11623exports.Search = Search;
11624});
11625
11626ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(acequire, exports, module) {
11627
11628var keyUtil = acequire("../lib/keys");
11629var useragent = acequire("../lib/useragent");
11630var KEY_MODS = keyUtil.KEY_MODS;
11631
11632function HashHandler(config, platform) {
11633 this.platform = platform || (useragent.isMac ? "mac" : "win");
11634 this.commands = {};
11635 this.commandKeyBinding = {};
11636 this.addCommands(config);
11637 this.$singleCommand = true;
11638}
11639
11640function MultiHashHandler(config, platform) {
11641 HashHandler.call(this, config, platform);
11642 this.$singleCommand = false;
11643}
11644
11645MultiHashHandler.prototype = HashHandler.prototype;
11646
11647(function() {
11648
11649
11650 this.addCommand = function(command) {
11651 if (this.commands[command.name])
11652 this.removeCommand(command);
11653
11654 this.commands[command.name] = command;
11655
11656 if (command.bindKey)
11657 this._buildKeyHash(command);
11658 };
11659
11660 this.removeCommand = function(command, keepCommand) {
11661 var name = command && (typeof command === 'string' ? command : command.name);
11662 command = this.commands[name];
11663 if (!keepCommand)
11664 delete this.commands[name];
11665 var ckb = this.commandKeyBinding;
11666 for (var keyId in ckb) {
11667 var cmdGroup = ckb[keyId];
11668 if (cmdGroup == command) {
11669 delete ckb[keyId];
11670 } else if (Array.isArray(cmdGroup)) {
11671 var i = cmdGroup.indexOf(command);
11672 if (i != -1) {
11673 cmdGroup.splice(i, 1);
11674 if (cmdGroup.length == 1)
11675 ckb[keyId] = cmdGroup[0];
11676 }
11677 }
11678 }
11679 };
11680
11681 this.bindKey = function(key, command, position) {
11682 if (typeof key == "object" && key) {
11683 if (position == undefined)
11684 position = key.position;
11685 key = key[this.platform];
11686 }
11687 if (!key)
11688 return;
11689 if (typeof command == "function")
11690 return this.addCommand({exec: command, bindKey: key, name: command.name || key});
11691
11692 key.split("|").forEach(function(keyPart) {
11693 var chain = "";
11694 if (keyPart.indexOf(" ") != -1) {
11695 var parts = keyPart.split(/\s+/);
11696 keyPart = parts.pop();
11697 parts.forEach(function(keyPart) {
11698 var binding = this.parseKeys(keyPart);
11699 var id = KEY_MODS[binding.hashId] + binding.key;
11700 chain += (chain ? " " : "") + id;
11701 this._addCommandToBinding(chain, "chainKeys");
11702 }, this);
11703 chain += " ";
11704 }
11705 var binding = this.parseKeys(keyPart);
11706 var id = KEY_MODS[binding.hashId] + binding.key;
11707 this._addCommandToBinding(chain + id, command, position);
11708 }, this);
11709 };
11710
11711 function getPosition(command) {
11712 return typeof command == "object" && command.bindKey
11713 && command.bindKey.position
11714 || (command.isDefault ? -100 : 0);
11715 }
11716 this._addCommandToBinding = function(keyId, command, position) {
11717 var ckb = this.commandKeyBinding, i;
11718 if (!command) {
11719 delete ckb[keyId];
11720 } else if (!ckb[keyId] || this.$singleCommand) {
11721 ckb[keyId] = command;
11722 } else {
11723 if (!Array.isArray(ckb[keyId])) {
11724 ckb[keyId] = [ckb[keyId]];
11725 } else if ((i = ckb[keyId].indexOf(command)) != -1) {
11726 ckb[keyId].splice(i, 1);
11727 }
11728
11729 if (typeof position != "number") {
11730 position = getPosition(command);
11731 }
11732
11733 var commands = ckb[keyId];
11734 for (i = 0; i < commands.length; i++) {
11735 var other = commands[i];
11736 var otherPos = getPosition(other);
11737 if (otherPos > position)
11738 break;
11739 }
11740 commands.splice(i, 0, command);
11741 }
11742 };
11743
11744 this.addCommands = function(commands) {
11745 commands && Object.keys(commands).forEach(function(name) {
11746 var command = commands[name];
11747 if (!command)
11748 return;
11749
11750 if (typeof command === "string")
11751 return this.bindKey(command, name);
11752
11753 if (typeof command === "function")
11754 command = { exec: command };
11755
11756 if (typeof command !== "object")
11757 return;
11758
11759 if (!command.name)
11760 command.name = name;
11761
11762 this.addCommand(command);
11763 }, this);
11764 };
11765
11766 this.removeCommands = function(commands) {
11767 Object.keys(commands).forEach(function(name) {
11768 this.removeCommand(commands[name]);
11769 }, this);
11770 };
11771
11772 this.bindKeys = function(keyList) {
11773 Object.keys(keyList).forEach(function(key) {
11774 this.bindKey(key, keyList[key]);
11775 }, this);
11776 };
11777
11778 this._buildKeyHash = function(command) {
11779 this.bindKey(command.bindKey, command);
11780 };
11781 this.parseKeys = function(keys) {
11782 var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x;});
11783 var key = parts.pop();
11784
11785 var keyCode = keyUtil[key];
11786 if (keyUtil.FUNCTION_KEYS[keyCode])
11787 key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();
11788 else if (!parts.length)
11789 return {key: key, hashId: -1};
11790 else if (parts.length == 1 && parts[0] == "shift")
11791 return {key: key.toUpperCase(), hashId: -1};
11792
11793 var hashId = 0;
11794 for (var i = parts.length; i--;) {
11795 var modifier = keyUtil.KEY_MODS[parts[i]];
11796 if (modifier == null) {
11797 if (typeof console != "undefined")
11798 console.error("invalid modifier " + parts[i] + " in " + keys);
11799 return false;
11800 }
11801 hashId |= modifier;
11802 }
11803 return {key: key, hashId: hashId};
11804 };
11805
11806 this.findKeyCommand = function findKeyCommand(hashId, keyString) {
11807 var key = KEY_MODS[hashId] + keyString;
11808 return this.commandKeyBinding[key];
11809 };
11810
11811 this.handleKeyboard = function(data, hashId, keyString, keyCode) {
11812 if (keyCode < 0) return;
11813 var key = KEY_MODS[hashId] + keyString;
11814 var command = this.commandKeyBinding[key];
11815 if (data.$keyChain) {
11816 data.$keyChain += " " + key;
11817 command = this.commandKeyBinding[data.$keyChain] || command;
11818 }
11819
11820 if (command) {
11821 if (command == "chainKeys" || command[command.length - 1] == "chainKeys") {
11822 data.$keyChain = data.$keyChain || key;
11823 return {command: "null"};
11824 }
11825 }
11826
11827 if (data.$keyChain) {
11828 if ((!hashId || hashId == 4) && keyString.length == 1)
11829 data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input
11830 else if (hashId == -1 || keyCode > 0)
11831 data.$keyChain = ""; // reset keyChain
11832 }
11833 return {command: command};
11834 };
11835
11836 this.getStatusText = function(editor, data) {
11837 return data.$keyChain || "";
11838 };
11839
11840}).call(HashHandler.prototype);
11841
11842exports.HashHandler = HashHandler;
11843exports.MultiHashHandler = MultiHashHandler;
11844});
11845
11846ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"], function(acequire, exports, module) {
11847
11848var oop = acequire("../lib/oop");
11849var MultiHashHandler = acequire("../keyboard/hash_handler").MultiHashHandler;
11850var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
11851
11852var CommandManager = function(platform, commands) {
11853 MultiHashHandler.call(this, commands, platform);
11854 this.byName = this.commands;
11855 this.setDefaultHandler("exec", function(e) {
11856 return e.command.exec(e.editor, e.args || {});
11857 });
11858};
11859
11860oop.inherits(CommandManager, MultiHashHandler);
11861
11862(function() {
11863
11864 oop.implement(this, EventEmitter);
11865
11866 this.exec = function(command, editor, args) {
11867 if (Array.isArray(command)) {
11868 for (var i = command.length; i--; ) {
11869 if (this.exec(command[i], editor, args)) return true;
11870 }
11871 return false;
11872 }
11873
11874 if (typeof command === "string")
11875 command = this.commands[command];
11876
11877 if (!command)
11878 return false;
11879
11880 if (editor && editor.$readOnly && !command.readOnly)
11881 return false;
11882
11883 if (command.isAvailable && !command.isAvailable(editor))
11884 return false;
11885
11886 var e = {editor: editor, command: command, args: args};
11887 e.returnValue = this._emit("exec", e);
11888 this._signal("afterExec", e);
11889
11890 return e.returnValue === false ? false : true;
11891 };
11892
11893 this.toggleRecording = function(editor) {
11894 if (this.$inReplay)
11895 return;
11896
11897 editor && editor._emit("changeStatus");
11898 if (this.recording) {
11899 this.macro.pop();
11900 this.removeEventListener("exec", this.$addCommandToMacro);
11901
11902 if (!this.macro.length)
11903 this.macro = this.oldMacro;
11904
11905 return this.recording = false;
11906 }
11907 if (!this.$addCommandToMacro) {
11908 this.$addCommandToMacro = function(e) {
11909 this.macro.push([e.command, e.args]);
11910 }.bind(this);
11911 }
11912
11913 this.oldMacro = this.macro;
11914 this.macro = [];
11915 this.on("exec", this.$addCommandToMacro);
11916 return this.recording = true;
11917 };
11918
11919 this.replay = function(editor) {
11920 if (this.$inReplay || !this.macro)
11921 return;
11922
11923 if (this.recording)
11924 return this.toggleRecording(editor);
11925
11926 try {
11927 this.$inReplay = true;
11928 this.macro.forEach(function(x) {
11929 if (typeof x == "string")
11930 this.exec(x, editor);
11931 else
11932 this.exec(x[0], editor, x[1]);
11933 }, this);
11934 } finally {
11935 this.$inReplay = false;
11936 }
11937 };
11938
11939 this.trimMacro = function(m) {
11940 return m.map(function(x){
11941 if (typeof x[0] != "string")
11942 x[0] = x[0].name;
11943 if (!x[1])
11944 x = x[0];
11945 return x;
11946 });
11947 };
11948
11949}).call(CommandManager.prototype);
11950
11951exports.CommandManager = CommandManager;
11952
11953});
11954
11955ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"], function(acequire, exports, module) {
11956
11957var lang = acequire("../lib/lang");
11958var config = acequire("../config");
11959var Range = acequire("../range").Range;
11960
11961function bindKey(win, mac) {
11962 return {win: win, mac: mac};
11963}
11964exports.commands = [{
11965 name: "showSettingsMenu",
11966 bindKey: bindKey("Ctrl-,", "Command-,"),
11967 exec: function(editor) {
11968 config.loadModule("ace/ext/settings_menu", function(module) {
11969 module.init(editor);
11970 editor.showSettingsMenu();
11971 });
11972 },
11973 readOnly: true
11974}, {
11975 name: "goToNextError",
11976 bindKey: bindKey("Alt-E", "F4"),
11977 exec: function(editor) {
11978 config.loadModule("ace/ext/error_marker", function(module) {
11979 module.showErrorMarker(editor, 1);
11980 });
11981 },
11982 scrollIntoView: "animate",
11983 readOnly: true
11984}, {
11985 name: "goToPreviousError",
11986 bindKey: bindKey("Alt-Shift-E", "Shift-F4"),
11987 exec: function(editor) {
11988 config.loadModule("ace/ext/error_marker", function(module) {
11989 module.showErrorMarker(editor, -1);
11990 });
11991 },
11992 scrollIntoView: "animate",
11993 readOnly: true
11994}, {
11995 name: "selectall",
11996 bindKey: bindKey("Ctrl-A", "Command-A"),
11997 exec: function(editor) { editor.selectAll(); },
11998 readOnly: true
11999}, {
12000 name: "centerselection",
12001 bindKey: bindKey(null, "Ctrl-L"),
12002 exec: function(editor) { editor.centerSelection(); },
12003 readOnly: true
12004}, {
12005 name: "gotoline",
12006 bindKey: bindKey("Ctrl-L", "Command-L"),
12007 exec: function(editor) {
12008 var line = parseInt(prompt("Enter line number:"), 10);
12009 if (!isNaN(line)) {
12010 editor.gotoLine(line);
12011 }
12012 },
12013 readOnly: true
12014}, {
12015 name: "fold",
12016 bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
12017 exec: function(editor) { editor.session.toggleFold(false); },
12018 multiSelectAction: "forEach",
12019 scrollIntoView: "center",
12020 readOnly: true
12021}, {
12022 name: "unfold",
12023 bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
12024 exec: function(editor) { editor.session.toggleFold(true); },
12025 multiSelectAction: "forEach",
12026 scrollIntoView: "center",
12027 readOnly: true
12028}, {
12029 name: "toggleFoldWidget",
12030 bindKey: bindKey("F2", "F2"),
12031 exec: function(editor) { editor.session.toggleFoldWidget(); },
12032 multiSelectAction: "forEach",
12033 scrollIntoView: "center",
12034 readOnly: true
12035}, {
12036 name: "toggleParentFoldWidget",
12037 bindKey: bindKey("Alt-F2", "Alt-F2"),
12038 exec: function(editor) { editor.session.toggleFoldWidget(true); },
12039 multiSelectAction: "forEach",
12040 scrollIntoView: "center",
12041 readOnly: true
12042}, {
12043 name: "foldall",
12044 bindKey: bindKey(null, "Ctrl-Command-Option-0"),
12045 exec: function(editor) { editor.session.foldAll(); },
12046 scrollIntoView: "center",
12047 readOnly: true
12048}, {
12049 name: "foldOther",
12050 bindKey: bindKey("Alt-0", "Command-Option-0"),
12051 exec: function(editor) {
12052 editor.session.foldAll();
12053 editor.session.unfold(editor.selection.getAllRanges());
12054 },
12055 scrollIntoView: "center",
12056 readOnly: true
12057}, {
12058 name: "unfoldall",
12059 bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
12060 exec: function(editor) { editor.session.unfold(); },
12061 scrollIntoView: "center",
12062 readOnly: true
12063}, {
12064 name: "findnext",
12065 bindKey: bindKey("Ctrl-K", "Command-G"),
12066 exec: function(editor) { editor.findNext(); },
12067 multiSelectAction: "forEach",
12068 scrollIntoView: "center",
12069 readOnly: true
12070}, {
12071 name: "findprevious",
12072 bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
12073 exec: function(editor) { editor.findPrevious(); },
12074 multiSelectAction: "forEach",
12075 scrollIntoView: "center",
12076 readOnly: true
12077}, {
12078 name: "selectOrFindNext",
12079 bindKey: bindKey("Alt-K", "Ctrl-G"),
12080 exec: function(editor) {
12081 if (editor.selection.isEmpty())
12082 editor.selection.selectWord();
12083 else
12084 editor.findNext();
12085 },
12086 readOnly: true
12087}, {
12088 name: "selectOrFindPrevious",
12089 bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"),
12090 exec: function(editor) {
12091 if (editor.selection.isEmpty())
12092 editor.selection.selectWord();
12093 else
12094 editor.findPrevious();
12095 },
12096 readOnly: true
12097}, {
12098 name: "find",
12099 bindKey: bindKey("Ctrl-F", "Command-F"),
12100 exec: function(editor) {
12101 config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor);});
12102 },
12103 readOnly: true
12104}, {
12105 name: "overwrite",
12106 bindKey: "Insert",
12107 exec: function(editor) { editor.toggleOverwrite(); },
12108 readOnly: true
12109}, {
12110 name: "selecttostart",
12111 bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Home|Command-Shift-Up"),
12112 exec: function(editor) { editor.getSelection().selectFileStart(); },
12113 multiSelectAction: "forEach",
12114 readOnly: true,
12115 scrollIntoView: "animate",
12116 aceCommandGroup: "fileJump"
12117}, {
12118 name: "gotostart",
12119 bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
12120 exec: function(editor) { editor.navigateFileStart(); },
12121 multiSelectAction: "forEach",
12122 readOnly: true,
12123 scrollIntoView: "animate",
12124 aceCommandGroup: "fileJump"
12125}, {
12126 name: "selectup",
12127 bindKey: bindKey("Shift-Up", "Shift-Up|Ctrl-Shift-P"),
12128 exec: function(editor) { editor.getSelection().selectUp(); },
12129 multiSelectAction: "forEach",
12130 scrollIntoView: "cursor",
12131 readOnly: true
12132}, {
12133 name: "golineup",
12134 bindKey: bindKey("Up", "Up|Ctrl-P"),
12135 exec: function(editor, args) { editor.navigateUp(args.times); },
12136 multiSelectAction: "forEach",
12137 scrollIntoView: "cursor",
12138 readOnly: true
12139}, {
12140 name: "selecttoend",
12141 bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-End|Command-Shift-Down"),
12142 exec: function(editor) { editor.getSelection().selectFileEnd(); },
12143 multiSelectAction: "forEach",
12144 readOnly: true,
12145 scrollIntoView: "animate",
12146 aceCommandGroup: "fileJump"
12147}, {
12148 name: "gotoend",
12149 bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
12150 exec: function(editor) { editor.navigateFileEnd(); },
12151 multiSelectAction: "forEach",
12152 readOnly: true,
12153 scrollIntoView: "animate",
12154 aceCommandGroup: "fileJump"
12155}, {
12156 name: "selectdown",
12157 bindKey: bindKey("Shift-Down", "Shift-Down|Ctrl-Shift-N"),
12158 exec: function(editor) { editor.getSelection().selectDown(); },
12159 multiSelectAction: "forEach",
12160 scrollIntoView: "cursor",
12161 readOnly: true
12162}, {
12163 name: "golinedown",
12164 bindKey: bindKey("Down", "Down|Ctrl-N"),
12165 exec: function(editor, args) { editor.navigateDown(args.times); },
12166 multiSelectAction: "forEach",
12167 scrollIntoView: "cursor",
12168 readOnly: true
12169}, {
12170 name: "selectwordleft",
12171 bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
12172 exec: function(editor) { editor.getSelection().selectWordLeft(); },
12173 multiSelectAction: "forEach",
12174 scrollIntoView: "cursor",
12175 readOnly: true
12176}, {
12177 name: "gotowordleft",
12178 bindKey: bindKey("Ctrl-Left", "Option-Left"),
12179 exec: function(editor) { editor.navigateWordLeft(); },
12180 multiSelectAction: "forEach",
12181 scrollIntoView: "cursor",
12182 readOnly: true
12183}, {
12184 name: "selecttolinestart",
12185 bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left|Ctrl-Shift-A"),
12186 exec: function(editor) { editor.getSelection().selectLineStart(); },
12187 multiSelectAction: "forEach",
12188 scrollIntoView: "cursor",
12189 readOnly: true
12190}, {
12191 name: "gotolinestart",
12192 bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
12193 exec: function(editor) { editor.navigateLineStart(); },
12194 multiSelectAction: "forEach",
12195 scrollIntoView: "cursor",
12196 readOnly: true
12197}, {
12198 name: "selectleft",
12199 bindKey: bindKey("Shift-Left", "Shift-Left|Ctrl-Shift-B"),
12200 exec: function(editor) { editor.getSelection().selectLeft(); },
12201 multiSelectAction: "forEach",
12202 scrollIntoView: "cursor",
12203 readOnly: true
12204}, {
12205 name: "gotoleft",
12206 bindKey: bindKey("Left", "Left|Ctrl-B"),
12207 exec: function(editor, args) { editor.navigateLeft(args.times); },
12208 multiSelectAction: "forEach",
12209 scrollIntoView: "cursor",
12210 readOnly: true
12211}, {
12212 name: "selectwordright",
12213 bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
12214 exec: function(editor) { editor.getSelection().selectWordRight(); },
12215 multiSelectAction: "forEach",
12216 scrollIntoView: "cursor",
12217 readOnly: true
12218}, {
12219 name: "gotowordright",
12220 bindKey: bindKey("Ctrl-Right", "Option-Right"),
12221 exec: function(editor) { editor.navigateWordRight(); },
12222 multiSelectAction: "forEach",
12223 scrollIntoView: "cursor",
12224 readOnly: true
12225}, {
12226 name: "selecttolineend",
12227 bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right|Shift-End|Ctrl-Shift-E"),
12228 exec: function(editor) { editor.getSelection().selectLineEnd(); },
12229 multiSelectAction: "forEach",
12230 scrollIntoView: "cursor",
12231 readOnly: true
12232}, {
12233 name: "gotolineend",
12234 bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
12235 exec: function(editor) { editor.navigateLineEnd(); },
12236 multiSelectAction: "forEach",
12237 scrollIntoView: "cursor",
12238 readOnly: true
12239}, {
12240 name: "selectright",
12241 bindKey: bindKey("Shift-Right", "Shift-Right"),
12242 exec: function(editor) { editor.getSelection().selectRight(); },
12243 multiSelectAction: "forEach",
12244 scrollIntoView: "cursor",
12245 readOnly: true
12246}, {
12247 name: "gotoright",
12248 bindKey: bindKey("Right", "Right|Ctrl-F"),
12249 exec: function(editor, args) { editor.navigateRight(args.times); },
12250 multiSelectAction: "forEach",
12251 scrollIntoView: "cursor",
12252 readOnly: true
12253}, {
12254 name: "selectpagedown",
12255 bindKey: "Shift-PageDown",
12256 exec: function(editor) { editor.selectPageDown(); },
12257 readOnly: true
12258}, {
12259 name: "pagedown",
12260 bindKey: bindKey(null, "Option-PageDown"),
12261 exec: function(editor) { editor.scrollPageDown(); },
12262 readOnly: true
12263}, {
12264 name: "gotopagedown",
12265 bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
12266 exec: function(editor) { editor.gotoPageDown(); },
12267 readOnly: true
12268}, {
12269 name: "selectpageup",
12270 bindKey: "Shift-PageUp",
12271 exec: function(editor) { editor.selectPageUp(); },
12272 readOnly: true
12273}, {
12274 name: "pageup",
12275 bindKey: bindKey(null, "Option-PageUp"),
12276 exec: function(editor) { editor.scrollPageUp(); },
12277 readOnly: true
12278}, {
12279 name: "gotopageup",
12280 bindKey: "PageUp",
12281 exec: function(editor) { editor.gotoPageUp(); },
12282 readOnly: true
12283}, {
12284 name: "scrollup",
12285 bindKey: bindKey("Ctrl-Up", null),
12286 exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
12287 readOnly: true
12288}, {
12289 name: "scrolldown",
12290 bindKey: bindKey("Ctrl-Down", null),
12291 exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
12292 readOnly: true
12293}, {
12294 name: "selectlinestart",
12295 bindKey: "Shift-Home",
12296 exec: function(editor) { editor.getSelection().selectLineStart(); },
12297 multiSelectAction: "forEach",
12298 scrollIntoView: "cursor",
12299 readOnly: true
12300}, {
12301 name: "selectlineend",
12302 bindKey: "Shift-End",
12303 exec: function(editor) { editor.getSelection().selectLineEnd(); },
12304 multiSelectAction: "forEach",
12305 scrollIntoView: "cursor",
12306 readOnly: true
12307}, {
12308 name: "togglerecording",
12309 bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
12310 exec: function(editor) { editor.commands.toggleRecording(editor); },
12311 readOnly: true
12312}, {
12313 name: "replaymacro",
12314 bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
12315 exec: function(editor) { editor.commands.replay(editor); },
12316 readOnly: true
12317}, {
12318 name: "jumptomatching",
12319 bindKey: bindKey("Ctrl-P", "Ctrl-P"),
12320 exec: function(editor) { editor.jumpToMatching(); },
12321 multiSelectAction: "forEach",
12322 scrollIntoView: "animate",
12323 readOnly: true
12324}, {
12325 name: "selecttomatching",
12326 bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
12327 exec: function(editor) { editor.jumpToMatching(true); },
12328 multiSelectAction: "forEach",
12329 scrollIntoView: "animate",
12330 readOnly: true
12331}, {
12332 name: "expandToMatching",
12333 bindKey: bindKey("Ctrl-Shift-M", "Ctrl-Shift-M"),
12334 exec: function(editor) { editor.jumpToMatching(true, true); },
12335 multiSelectAction: "forEach",
12336 scrollIntoView: "animate",
12337 readOnly: true
12338}, {
12339 name: "passKeysToBrowser",
12340 bindKey: bindKey(null, null),
12341 exec: function() {},
12342 passEvent: true,
12343 readOnly: true
12344}, {
12345 name: "copy",
12346 exec: function(editor) {
12347 },
12348 readOnly: true
12349},
12350{
12351 name: "cut",
12352 exec: function(editor) {
12353 var range = editor.getSelectionRange();
12354 editor._emit("cut", range);
12355
12356 if (!editor.selection.isEmpty()) {
12357 editor.session.remove(range);
12358 editor.clearSelection();
12359 }
12360 },
12361 scrollIntoView: "cursor",
12362 multiSelectAction: "forEach"
12363}, {
12364 name: "paste",
12365 exec: function(editor, args) {
12366 editor.$handlePaste(args);
12367 },
12368 scrollIntoView: "cursor"
12369}, {
12370 name: "removeline",
12371 bindKey: bindKey("Ctrl-D", "Command-D"),
12372 exec: function(editor) { editor.removeLines(); },
12373 scrollIntoView: "cursor",
12374 multiSelectAction: "forEachLine"
12375}, {
12376 name: "duplicateSelection",
12377 bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
12378 exec: function(editor) { editor.duplicateSelection(); },
12379 scrollIntoView: "cursor",
12380 multiSelectAction: "forEach"
12381}, {
12382 name: "sortlines",
12383 bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
12384 exec: function(editor) { editor.sortLines(); },
12385 scrollIntoView: "selection",
12386 multiSelectAction: "forEachLine"
12387}, {
12388 name: "togglecomment",
12389 bindKey: bindKey("Ctrl-/", "Command-/"),
12390 exec: function(editor) { editor.toggleCommentLines(); },
12391 multiSelectAction: "forEachLine",
12392 scrollIntoView: "selectionPart"
12393}, {
12394 name: "toggleBlockComment",
12395 bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
12396 exec: function(editor) { editor.toggleBlockComment(); },
12397 multiSelectAction: "forEach",
12398 scrollIntoView: "selectionPart"
12399}, {
12400 name: "modifyNumberUp",
12401 bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
12402 exec: function(editor) { editor.modifyNumber(1); },
12403 scrollIntoView: "cursor",
12404 multiSelectAction: "forEach"
12405}, {
12406 name: "modifyNumberDown",
12407 bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
12408 exec: function(editor) { editor.modifyNumber(-1); },
12409 scrollIntoView: "cursor",
12410 multiSelectAction: "forEach"
12411}, {
12412 name: "replace",
12413 bindKey: bindKey("Ctrl-H", "Command-Option-F"),
12414 exec: function(editor) {
12415 config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true);});
12416 }
12417}, {
12418 name: "undo",
12419 bindKey: bindKey("Ctrl-Z", "Command-Z"),
12420 exec: function(editor) { editor.undo(); }
12421}, {
12422 name: "redo",
12423 bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
12424 exec: function(editor) { editor.redo(); }
12425}, {
12426 name: "copylinesup",
12427 bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
12428 exec: function(editor) { editor.copyLinesUp(); },
12429 scrollIntoView: "cursor"
12430}, {
12431 name: "movelinesup",
12432 bindKey: bindKey("Alt-Up", "Option-Up"),
12433 exec: function(editor) { editor.moveLinesUp(); },
12434 scrollIntoView: "cursor"
12435}, {
12436 name: "copylinesdown",
12437 bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
12438 exec: function(editor) { editor.copyLinesDown(); },
12439 scrollIntoView: "cursor"
12440}, {
12441 name: "movelinesdown",
12442 bindKey: bindKey("Alt-Down", "Option-Down"),
12443 exec: function(editor) { editor.moveLinesDown(); },
12444 scrollIntoView: "cursor"
12445}, {
12446 name: "del",
12447 bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"),
12448 exec: function(editor) { editor.remove("right"); },
12449 multiSelectAction: "forEach",
12450 scrollIntoView: "cursor"
12451}, {
12452 name: "backspace",
12453 bindKey: bindKey(
12454 "Shift-Backspace|Backspace",
12455 "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"
12456 ),
12457 exec: function(editor) { editor.remove("left"); },
12458 multiSelectAction: "forEach",
12459 scrollIntoView: "cursor"
12460}, {
12461 name: "cut_or_delete",
12462 bindKey: bindKey("Shift-Delete", null),
12463 exec: function(editor) {
12464 if (editor.selection.isEmpty()) {
12465 editor.remove("left");
12466 } else {
12467 return false;
12468 }
12469 },
12470 multiSelectAction: "forEach",
12471 scrollIntoView: "cursor"
12472}, {
12473 name: "removetolinestart",
12474 bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
12475 exec: function(editor) { editor.removeToLineStart(); },
12476 multiSelectAction: "forEach",
12477 scrollIntoView: "cursor"
12478}, {
12479 name: "removetolineend",
12480 bindKey: bindKey("Alt-Delete", "Ctrl-K|Command-Delete"),
12481 exec: function(editor) { editor.removeToLineEnd(); },
12482 multiSelectAction: "forEach",
12483 scrollIntoView: "cursor"
12484}, {
12485 name: "removetolinestarthard",
12486 bindKey: bindKey("Ctrl-Shift-Backspace", null),
12487 exec: function(editor) {
12488 var range = editor.selection.getRange();
12489 range.start.column = 0;
12490 editor.session.remove(range);
12491 },
12492 multiSelectAction: "forEach",
12493 scrollIntoView: "cursor"
12494}, {
12495 name: "removetolineendhard",
12496 bindKey: bindKey("Ctrl-Shift-Delete", null),
12497 exec: function(editor) {
12498 var range = editor.selection.getRange();
12499 range.end.column = Number.MAX_VALUE;
12500 editor.session.remove(range);
12501 },
12502 multiSelectAction: "forEach",
12503 scrollIntoView: "cursor"
12504}, {
12505 name: "removewordleft",
12506 bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
12507 exec: function(editor) { editor.removeWordLeft(); },
12508 multiSelectAction: "forEach",
12509 scrollIntoView: "cursor"
12510}, {
12511 name: "removewordright",
12512 bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
12513 exec: function(editor) { editor.removeWordRight(); },
12514 multiSelectAction: "forEach",
12515 scrollIntoView: "cursor"
12516}, {
12517 name: "outdent",
12518 bindKey: bindKey("Shift-Tab", "Shift-Tab"),
12519 exec: function(editor) { editor.blockOutdent(); },
12520 multiSelectAction: "forEach",
12521 scrollIntoView: "selectionPart"
12522}, {
12523 name: "indent",
12524 bindKey: bindKey("Tab", "Tab"),
12525 exec: function(editor) { editor.indent(); },
12526 multiSelectAction: "forEach",
12527 scrollIntoView: "selectionPart"
12528}, {
12529 name: "blockoutdent",
12530 bindKey: bindKey("Ctrl-[", "Ctrl-["),
12531 exec: function(editor) { editor.blockOutdent(); },
12532 multiSelectAction: "forEachLine",
12533 scrollIntoView: "selectionPart"
12534}, {
12535 name: "blockindent",
12536 bindKey: bindKey("Ctrl-]", "Ctrl-]"),
12537 exec: function(editor) { editor.blockIndent(); },
12538 multiSelectAction: "forEachLine",
12539 scrollIntoView: "selectionPart"
12540}, {
12541 name: "insertstring",
12542 exec: function(editor, str) { editor.insert(str); },
12543 multiSelectAction: "forEach",
12544 scrollIntoView: "cursor"
12545}, {
12546 name: "inserttext",
12547 exec: function(editor, args) {
12548 editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
12549 },
12550 multiSelectAction: "forEach",
12551 scrollIntoView: "cursor"
12552}, {
12553 name: "splitline",
12554 bindKey: bindKey(null, "Ctrl-O"),
12555 exec: function(editor) { editor.splitLine(); },
12556 multiSelectAction: "forEach",
12557 scrollIntoView: "cursor"
12558}, {
12559 name: "transposeletters",
12560 bindKey: bindKey("Alt-Shift-X", "Ctrl-T"),
12561 exec: function(editor) { editor.transposeLetters(); },
12562 multiSelectAction: function(editor) {editor.transposeSelections(1); },
12563 scrollIntoView: "cursor"
12564}, {
12565 name: "touppercase",
12566 bindKey: bindKey("Ctrl-U", "Ctrl-U"),
12567 exec: function(editor) { editor.toUpperCase(); },
12568 multiSelectAction: "forEach",
12569 scrollIntoView: "cursor"
12570}, {
12571 name: "tolowercase",
12572 bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
12573 exec: function(editor) { editor.toLowerCase(); },
12574 multiSelectAction: "forEach",
12575 scrollIntoView: "cursor"
12576}, {
12577 name: "expandtoline",
12578 bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"),
12579 exec: function(editor) {
12580 var range = editor.selection.getRange();
12581
12582 range.start.column = range.end.column = 0;
12583 range.end.row++;
12584 editor.selection.setRange(range, false);
12585 },
12586 multiSelectAction: "forEach",
12587 scrollIntoView: "cursor",
12588 readOnly: true
12589}, {
12590 name: "joinlines",
12591 bindKey: bindKey(null, null),
12592 exec: function(editor) {
12593 var isBackwards = editor.selection.isBackwards();
12594 var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();
12595 var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();
12596 var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length;
12597 var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());
12598 var selectedCount = selectedText.replace(/\n\s*/, " ").length;
12599 var insertLine = editor.session.doc.getLine(selectionStart.row);
12600
12601 for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) {
12602 var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i)));
12603 if (curLine.length !== 0) {
12604 curLine = " " + curLine;
12605 }
12606 insertLine += curLine;
12607 }
12608
12609 if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {
12610 insertLine += editor.session.doc.getNewLineCharacter();
12611 }
12612
12613 editor.clearSelection();
12614 editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);
12615
12616 if (selectedCount > 0) {
12617 editor.selection.moveCursorTo(selectionStart.row, selectionStart.column);
12618 editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount);
12619 } else {
12620 firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol;
12621 editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol);
12622 }
12623 },
12624 multiSelectAction: "forEach",
12625 readOnly: true
12626}, {
12627 name: "invertSelection",
12628 bindKey: bindKey(null, null),
12629 exec: function(editor) {
12630 var endRow = editor.session.doc.getLength() - 1;
12631 var endCol = editor.session.doc.getLine(endRow).length;
12632 var ranges = editor.selection.rangeList.ranges;
12633 var newRanges = [];
12634 if (ranges.length < 1) {
12635 ranges = [editor.selection.getRange()];
12636 }
12637
12638 for (var i = 0; i < ranges.length; i++) {
12639 if (i == (ranges.length - 1)) {
12640 if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) {
12641 newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol));
12642 }
12643 }
12644
12645 if (i === 0) {
12646 if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) {
12647 newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column));
12648 }
12649 } else {
12650 newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column));
12651 }
12652 }
12653
12654 editor.exitMultiSelectMode();
12655 editor.clearSelection();
12656
12657 for(var i = 0; i < newRanges.length; i++) {
12658 editor.selection.addRange(newRanges[i], false);
12659 }
12660 },
12661 readOnly: true,
12662 scrollIntoView: "none"
12663}];
12664
12665});
12666
12667ace.define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator"], function(acequire, exports, module) {
12668
12669acequire("./lib/fixoldbrowsers");
12670
12671var oop = acequire("./lib/oop");
12672var dom = acequire("./lib/dom");
12673var lang = acequire("./lib/lang");
12674var useragent = acequire("./lib/useragent");
12675var TextInput = acequire("./keyboard/textinput").TextInput;
12676var MouseHandler = acequire("./mouse/mouse_handler").MouseHandler;
12677var FoldHandler = acequire("./mouse/fold_handler").FoldHandler;
12678var KeyBinding = acequire("./keyboard/keybinding").KeyBinding;
12679var EditSession = acequire("./edit_session").EditSession;
12680var Search = acequire("./search").Search;
12681var Range = acequire("./range").Range;
12682var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
12683var CommandManager = acequire("./commands/command_manager").CommandManager;
12684var defaultCommands = acequire("./commands/default_commands").commands;
12685var config = acequire("./config");
12686var TokenIterator = acequire("./token_iterator").TokenIterator;
12687var Editor = function(renderer, session) {
12688 var container = renderer.getContainerElement();
12689 this.container = container;
12690 this.renderer = renderer;
12691 this.id = "editor" + (++Editor.$uid);
12692
12693 this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
12694 if (typeof document == "object") {
12695 this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
12696 this.renderer.textarea = this.textInput.getElement();
12697 this.$mouseHandler = new MouseHandler(this);
12698 new FoldHandler(this);
12699 }
12700
12701 this.keyBinding = new KeyBinding(this);
12702
12703 this.$blockScrolling = 0;
12704 this.$search = new Search().set({
12705 wrap: true
12706 });
12707
12708 this.$historyTracker = this.$historyTracker.bind(this);
12709 this.commands.on("exec", this.$historyTracker);
12710
12711 this.$initOperationListeners();
12712
12713 this._$emitInputEvent = lang.delayedCall(function() {
12714 this._signal("input", {});
12715 if (this.session && this.session.bgTokenizer)
12716 this.session.bgTokenizer.scheduleStart();
12717 }.bind(this));
12718
12719 this.on("change", function(_, _self) {
12720 _self._$emitInputEvent.schedule(31);
12721 });
12722
12723 this.setSession(session || new EditSession(""));
12724 config.resetOptions(this);
12725 config._signal("editor", this);
12726};
12727
12728Editor.$uid = 0;
12729
12730(function(){
12731
12732 oop.implement(this, EventEmitter);
12733
12734 this.$initOperationListeners = function() {
12735
12736 this.selections = [];
12737 this.commands.on("exec", this.startOperation.bind(this), true);
12738 this.commands.on("afterExec", this.endOperation.bind(this), true);
12739
12740 this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
12741
12742 this.on("change", function() {
12743 this.curOp || this.startOperation();
12744 this.curOp.docChanged = true;
12745 }.bind(this), true);
12746
12747 this.on("changeSelection", function() {
12748 this.curOp || this.startOperation();
12749 this.curOp.selectionChanged = true;
12750 }.bind(this), true);
12751 };
12752
12753 this.curOp = null;
12754 this.prevOp = {};
12755 this.startOperation = function(commadEvent) {
12756 if (this.curOp) {
12757 if (!commadEvent || this.curOp.command)
12758 return;
12759 this.prevOp = this.curOp;
12760 }
12761 if (!commadEvent) {
12762 this.previousCommand = null;
12763 commadEvent = {};
12764 }
12765
12766 this.$opResetTimer.schedule();
12767 this.curOp = {
12768 command: commadEvent.command || {},
12769 args: commadEvent.args,
12770 scrollTop: this.renderer.scrollTop
12771 };
12772 if (this.curOp.command.name && this.curOp.command.scrollIntoView !== undefined)
12773 this.$blockScrolling++;
12774 };
12775
12776 this.endOperation = function(e) {
12777 if (this.curOp) {
12778 if (e && e.returnValue === false)
12779 return this.curOp = null;
12780 this._signal("beforeEndOperation");
12781 var command = this.curOp.command;
12782 if (command.name && this.$blockScrolling > 0)
12783 this.$blockScrolling--;
12784 var scrollIntoView = command && command.scrollIntoView;
12785 if (scrollIntoView) {
12786 switch (scrollIntoView) {
12787 case "center-animate":
12788 scrollIntoView = "animate";
12789 case "center":
12790 this.renderer.scrollCursorIntoView(null, 0.5);
12791 break;
12792 case "animate":
12793 case "cursor":
12794 this.renderer.scrollCursorIntoView();
12795 break;
12796 case "selectionPart":
12797 var range = this.selection.getRange();
12798 var config = this.renderer.layerConfig;
12799 if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
12800 this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
12801 }
12802 break;
12803 }
12804 if (scrollIntoView == "animate")
12805 this.renderer.animateScrolling(this.curOp.scrollTop);
12806 }
12807
12808 this.prevOp = this.curOp;
12809 this.curOp = null;
12810 }
12811 };
12812 this.$mergeableCommands = ["backspace", "del", "insertstring"];
12813 this.$historyTracker = function(e) {
12814 if (!this.$mergeUndoDeltas)
12815 return;
12816
12817 var prev = this.prevOp;
12818 var mergeableCommands = this.$mergeableCommands;
12819 var shouldMerge = prev.command && (e.command.name == prev.command.name);
12820 if (e.command.name == "insertstring") {
12821 var text = e.args;
12822 if (this.mergeNextCommand === undefined)
12823 this.mergeNextCommand = true;
12824
12825 shouldMerge = shouldMerge
12826 && this.mergeNextCommand // previous command allows to coalesce with
12827 && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
12828
12829 this.mergeNextCommand = true;
12830 } else {
12831 shouldMerge = shouldMerge
12832 && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
12833 }
12834
12835 if (
12836 this.$mergeUndoDeltas != "always"
12837 && Date.now() - this.sequenceStartTime > 2000
12838 ) {
12839 shouldMerge = false; // the sequence is too long
12840 }
12841
12842 if (shouldMerge)
12843 this.session.mergeUndoDeltas = true;
12844 else if (mergeableCommands.indexOf(e.command.name) !== -1)
12845 this.sequenceStartTime = Date.now();
12846 };
12847 this.setKeyboardHandler = function(keyboardHandler, cb) {
12848 if (keyboardHandler && typeof keyboardHandler === "string") {
12849 this.$keybindingId = keyboardHandler;
12850 var _self = this;
12851 config.loadModule(["keybinding", keyboardHandler], function(module) {
12852 if (_self.$keybindingId == keyboardHandler)
12853 _self.keyBinding.setKeyboardHandler(module && module.handler);
12854 cb && cb();
12855 });
12856 } else {
12857 this.$keybindingId = null;
12858 this.keyBinding.setKeyboardHandler(keyboardHandler);
12859 cb && cb();
12860 }
12861 };
12862 this.getKeyboardHandler = function() {
12863 return this.keyBinding.getKeyboardHandler();
12864 };
12865 this.setSession = function(session) {
12866 if (this.session == session)
12867 return;
12868 if (this.curOp) this.endOperation();
12869 this.curOp = {};
12870
12871 var oldSession = this.session;
12872 if (oldSession) {
12873 this.session.off("change", this.$onDocumentChange);
12874 this.session.off("changeMode", this.$onChangeMode);
12875 this.session.off("tokenizerUpdate", this.$onTokenizerUpdate);
12876 this.session.off("changeTabSize", this.$onChangeTabSize);
12877 this.session.off("changeWrapLimit", this.$onChangeWrapLimit);
12878 this.session.off("changeWrapMode", this.$onChangeWrapMode);
12879 this.session.off("changeFold", this.$onChangeFold);
12880 this.session.off("changeFrontMarker", this.$onChangeFrontMarker);
12881 this.session.off("changeBackMarker", this.$onChangeBackMarker);
12882 this.session.off("changeBreakpoint", this.$onChangeBreakpoint);
12883 this.session.off("changeAnnotation", this.$onChangeAnnotation);
12884 this.session.off("changeOverwrite", this.$onCursorChange);
12885 this.session.off("changeScrollTop", this.$onScrollTopChange);
12886 this.session.off("changeScrollLeft", this.$onScrollLeftChange);
12887
12888 var selection = this.session.getSelection();
12889 selection.off("changeCursor", this.$onCursorChange);
12890 selection.off("changeSelection", this.$onSelectionChange);
12891 }
12892
12893 this.session = session;
12894 if (session) {
12895 this.$onDocumentChange = this.onDocumentChange.bind(this);
12896 session.on("change", this.$onDocumentChange);
12897 this.renderer.setSession(session);
12898
12899 this.$onChangeMode = this.onChangeMode.bind(this);
12900 session.on("changeMode", this.$onChangeMode);
12901
12902 this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
12903 session.on("tokenizerUpdate", this.$onTokenizerUpdate);
12904
12905 this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
12906 session.on("changeTabSize", this.$onChangeTabSize);
12907
12908 this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
12909 session.on("changeWrapLimit", this.$onChangeWrapLimit);
12910
12911 this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
12912 session.on("changeWrapMode", this.$onChangeWrapMode);
12913
12914 this.$onChangeFold = this.onChangeFold.bind(this);
12915 session.on("changeFold", this.$onChangeFold);
12916
12917 this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
12918 this.session.on("changeFrontMarker", this.$onChangeFrontMarker);
12919
12920 this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
12921 this.session.on("changeBackMarker", this.$onChangeBackMarker);
12922
12923 this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
12924 this.session.on("changeBreakpoint", this.$onChangeBreakpoint);
12925
12926 this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
12927 this.session.on("changeAnnotation", this.$onChangeAnnotation);
12928
12929 this.$onCursorChange = this.onCursorChange.bind(this);
12930 this.session.on("changeOverwrite", this.$onCursorChange);
12931
12932 this.$onScrollTopChange = this.onScrollTopChange.bind(this);
12933 this.session.on("changeScrollTop", this.$onScrollTopChange);
12934
12935 this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
12936 this.session.on("changeScrollLeft", this.$onScrollLeftChange);
12937
12938 this.selection = session.getSelection();
12939 this.selection.on("changeCursor", this.$onCursorChange);
12940
12941 this.$onSelectionChange = this.onSelectionChange.bind(this);
12942 this.selection.on("changeSelection", this.$onSelectionChange);
12943
12944 this.onChangeMode();
12945
12946 this.$blockScrolling += 1;
12947 this.onCursorChange();
12948 this.$blockScrolling -= 1;
12949
12950 this.onScrollTopChange();
12951 this.onScrollLeftChange();
12952 this.onSelectionChange();
12953 this.onChangeFrontMarker();
12954 this.onChangeBackMarker();
12955 this.onChangeBreakpoint();
12956 this.onChangeAnnotation();
12957 this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
12958 this.renderer.updateFull();
12959 } else {
12960 this.selection = null;
12961 this.renderer.setSession(session);
12962 }
12963
12964 this._signal("changeSession", {
12965 session: session,
12966 oldSession: oldSession
12967 });
12968
12969 this.curOp = null;
12970
12971 oldSession && oldSession._signal("changeEditor", {oldEditor: this});
12972 session && session._signal("changeEditor", {editor: this});
12973
12974 if (session && session.bgTokenizer)
12975 session.bgTokenizer.scheduleStart();
12976 };
12977 this.getSession = function() {
12978 return this.session;
12979 };
12980 this.setValue = function(val, cursorPos) {
12981 this.session.doc.setValue(val);
12982
12983 if (!cursorPos)
12984 this.selectAll();
12985 else if (cursorPos == 1)
12986 this.navigateFileEnd();
12987 else if (cursorPos == -1)
12988 this.navigateFileStart();
12989
12990 return val;
12991 };
12992 this.getValue = function() {
12993 return this.session.getValue();
12994 };
12995 this.getSelection = function() {
12996 return this.selection;
12997 };
12998 this.resize = function(force) {
12999 this.renderer.onResize(force);
13000 };
13001 this.setTheme = function(theme, cb) {
13002 this.renderer.setTheme(theme, cb);
13003 };
13004 this.getTheme = function() {
13005 return this.renderer.getTheme();
13006 };
13007 this.setStyle = function(style) {
13008 this.renderer.setStyle(style);
13009 };
13010 this.unsetStyle = function(style) {
13011 this.renderer.unsetStyle(style);
13012 };
13013 this.getFontSize = function () {
13014 return this.getOption("fontSize") ||
13015 dom.computedStyle(this.container, "fontSize");
13016 };
13017 this.setFontSize = function(size) {
13018 this.setOption("fontSize", size);
13019 };
13020
13021 this.$highlightBrackets = function() {
13022 if (this.session.$bracketHighlight) {
13023 this.session.removeMarker(this.session.$bracketHighlight);
13024 this.session.$bracketHighlight = null;
13025 }
13026
13027 if (this.$highlightPending) {
13028 return;
13029 }
13030 var self = this;
13031 this.$highlightPending = true;
13032 setTimeout(function() {
13033 self.$highlightPending = false;
13034 var session = self.session;
13035 if (!session || !session.bgTokenizer) return;
13036 var pos = session.findMatchingBracket(self.getCursorPosition());
13037 if (pos) {
13038 var range = new Range(pos.row, pos.column, pos.row, pos.column + 1);
13039 } else if (session.$mode.getMatching) {
13040 var range = session.$mode.getMatching(self.session);
13041 }
13042 if (range)
13043 session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text");
13044 }, 50);
13045 };
13046 this.$highlightTags = function() {
13047 if (this.$highlightTagPending)
13048 return;
13049 var self = this;
13050 this.$highlightTagPending = true;
13051 setTimeout(function() {
13052 self.$highlightTagPending = false;
13053
13054 var session = self.session;
13055 if (!session || !session.bgTokenizer) return;
13056
13057 var pos = self.getCursorPosition();
13058 var iterator = new TokenIterator(self.session, pos.row, pos.column);
13059 var token = iterator.getCurrentToken();
13060
13061 if (!token || !/\b(?:tag-open|tag-name)/.test(token.type)) {
13062 session.removeMarker(session.$tagHighlight);
13063 session.$tagHighlight = null;
13064 return;
13065 }
13066
13067 if (token.type.indexOf("tag-open") != -1) {
13068 token = iterator.stepForward();
13069 if (!token)
13070 return;
13071 }
13072
13073 var tag = token.value;
13074 var depth = 0;
13075 var prevToken = iterator.stepBackward();
13076
13077 if (prevToken.value == '<'){
13078 do {
13079 prevToken = token;
13080 token = iterator.stepForward();
13081
13082 if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
13083 if (prevToken.value === '<'){
13084 depth++;
13085 } else if (prevToken.value === '</'){
13086 depth--;
13087 }
13088 }
13089
13090 } while (token && depth >= 0);
13091 } else {
13092 do {
13093 token = prevToken;
13094 prevToken = iterator.stepBackward();
13095
13096 if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
13097 if (prevToken.value === '<') {
13098 depth++;
13099 } else if (prevToken.value === '</') {
13100 depth--;
13101 }
13102 }
13103 } while (prevToken && depth <= 0);
13104 iterator.stepForward();
13105 }
13106
13107 if (!token) {
13108 session.removeMarker(session.$tagHighlight);
13109 session.$tagHighlight = null;
13110 return;
13111 }
13112
13113 var row = iterator.getCurrentTokenRow();
13114 var column = iterator.getCurrentTokenColumn();
13115 var range = new Range(row, column, row, column+token.value.length);
13116 var sbm = session.$backMarkers[session.$tagHighlight];
13117 if (session.$tagHighlight && sbm != undefined && range.compareRange(sbm.range) !== 0) {
13118 session.removeMarker(session.$tagHighlight);
13119 session.$tagHighlight = null;
13120 }
13121
13122 if (range && !session.$tagHighlight)
13123 session.$tagHighlight = session.addMarker(range, "ace_bracket", "text");
13124 }, 50);
13125 };
13126 this.focus = function() {
13127 var _self = this;
13128 setTimeout(function() {
13129 _self.textInput.focus();
13130 });
13131 this.textInput.focus();
13132 };
13133 this.isFocused = function() {
13134 return this.textInput.isFocused();
13135 };
13136 this.blur = function() {
13137 this.textInput.blur();
13138 };
13139 this.onFocus = function(e) {
13140 if (this.$isFocused)
13141 return;
13142 this.$isFocused = true;
13143 this.renderer.showCursor();
13144 this.renderer.visualizeFocus();
13145 this._emit("focus", e);
13146 };
13147 this.onBlur = function(e) {
13148 if (!this.$isFocused)
13149 return;
13150 this.$isFocused = false;
13151 this.renderer.hideCursor();
13152 this.renderer.visualizeBlur();
13153 this._emit("blur", e);
13154 };
13155
13156 this.$cursorChange = function() {
13157 this.renderer.updateCursor();
13158 };
13159 this.onDocumentChange = function(delta) {
13160 var wrap = this.session.$useWrapMode;
13161 var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);
13162 this.renderer.updateLines(delta.start.row, lastRow, wrap);
13163
13164 this._signal("change", delta);
13165 this.$cursorChange();
13166 this.$updateHighlightActiveLine();
13167 };
13168
13169 this.onTokenizerUpdate = function(e) {
13170 var rows = e.data;
13171 this.renderer.updateLines(rows.first, rows.last);
13172 };
13173
13174
13175 this.onScrollTopChange = function() {
13176 this.renderer.scrollToY(this.session.getScrollTop());
13177 };
13178
13179 this.onScrollLeftChange = function() {
13180 this.renderer.scrollToX(this.session.getScrollLeft());
13181 };
13182 this.onCursorChange = function() {
13183 this.$cursorChange();
13184
13185 if (!this.$blockScrolling) {
13186 config.warn("Automatically scrolling cursor into view after selection change",
13187 "this will be disabled in the next version",
13188 "set editor.$blockScrolling = Infinity to disable this message"
13189 );
13190 this.renderer.scrollCursorIntoView();
13191 }
13192
13193 this.$highlightBrackets();
13194 this.$highlightTags();
13195 this.$updateHighlightActiveLine();
13196 this._signal("changeSelection");
13197 };
13198
13199 this.$updateHighlightActiveLine = function() {
13200 var session = this.getSession();
13201
13202 var highlight;
13203 if (this.$highlightActiveLine) {
13204 if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
13205 highlight = this.getCursorPosition();
13206 if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
13207 highlight = false;
13208 }
13209
13210 if (session.$highlightLineMarker && !highlight) {
13211 session.removeMarker(session.$highlightLineMarker.id);
13212 session.$highlightLineMarker = null;
13213 } else if (!session.$highlightLineMarker && highlight) {
13214 var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
13215 range.id = session.addMarker(range, "ace_active-line", "screenLine");
13216 session.$highlightLineMarker = range;
13217 } else if (highlight) {
13218 session.$highlightLineMarker.start.row = highlight.row;
13219 session.$highlightLineMarker.end.row = highlight.row;
13220 session.$highlightLineMarker.start.column = highlight.column;
13221 session._signal("changeBackMarker");
13222 }
13223 };
13224
13225 this.onSelectionChange = function(e) {
13226 var session = this.session;
13227
13228 if (session.$selectionMarker) {
13229 session.removeMarker(session.$selectionMarker);
13230 }
13231 session.$selectionMarker = null;
13232
13233 if (!this.selection.isEmpty()) {
13234 var range = this.selection.getRange();
13235 var style = this.getSelectionStyle();
13236 session.$selectionMarker = session.addMarker(range, "ace_selection", style);
13237 } else {
13238 this.$updateHighlightActiveLine();
13239 }
13240
13241 var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
13242 this.session.highlight(re);
13243
13244 this._signal("changeSelection");
13245 };
13246
13247 this.$getSelectionHighLightRegexp = function() {
13248 var session = this.session;
13249
13250 var selection = this.getSelectionRange();
13251 if (selection.isEmpty() || selection.isMultiLine())
13252 return;
13253
13254 var startOuter = selection.start.column - 1;
13255 var endOuter = selection.end.column + 1;
13256 var line = session.getLine(selection.start.row);
13257 var lineCols = line.length;
13258 var needle = line.substring(Math.max(startOuter, 0),
13259 Math.min(endOuter, lineCols));
13260 if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
13261 (endOuter <= lineCols && /[\w\d]$/.test(needle)))
13262 return;
13263
13264 needle = line.substring(selection.start.column, selection.end.column);
13265 if (!/^[\w\d]+$/.test(needle))
13266 return;
13267
13268 var re = this.$search.$assembleRegExp({
13269 wholeWord: true,
13270 caseSensitive: true,
13271 needle: needle
13272 });
13273
13274 return re;
13275 };
13276
13277
13278 this.onChangeFrontMarker = function() {
13279 this.renderer.updateFrontMarkers();
13280 };
13281
13282 this.onChangeBackMarker = function() {
13283 this.renderer.updateBackMarkers();
13284 };
13285
13286
13287 this.onChangeBreakpoint = function() {
13288 this.renderer.updateBreakpoints();
13289 };
13290
13291 this.onChangeAnnotation = function() {
13292 this.renderer.setAnnotations(this.session.getAnnotations());
13293 };
13294
13295
13296 this.onChangeMode = function(e) {
13297 this.renderer.updateText();
13298 this._emit("changeMode", e);
13299 };
13300
13301
13302 this.onChangeWrapLimit = function() {
13303 this.renderer.updateFull();
13304 };
13305
13306 this.onChangeWrapMode = function() {
13307 this.renderer.onResize(true);
13308 };
13309
13310
13311 this.onChangeFold = function() {
13312 this.$updateHighlightActiveLine();
13313 this.renderer.updateFull();
13314 };
13315 this.getSelectedText = function() {
13316 return this.session.getTextRange(this.getSelectionRange());
13317 };
13318 this.getCopyText = function() {
13319 var text = this.getSelectedText();
13320 this._signal("copy", text);
13321 return text;
13322 };
13323 this.onCopy = function() {
13324 this.commands.exec("copy", this);
13325 };
13326 this.onCut = function() {
13327 this.commands.exec("cut", this);
13328 };
13329 this.onPaste = function(text, event) {
13330 var e = {text: text, event: event};
13331 this.commands.exec("paste", this, e);
13332 };
13333
13334 this.$handlePaste = function(e) {
13335 if (typeof e == "string")
13336 e = {text: e};
13337 this._signal("paste", e);
13338 var text = e.text;
13339 if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
13340 this.insert(text);
13341 } else {
13342 var lines = text.split(/\r\n|\r|\n/);
13343 var ranges = this.selection.rangeList.ranges;
13344
13345 if (lines.length > ranges.length || lines.length < 2 || !lines[1])
13346 return this.commands.exec("insertstring", this, text);
13347
13348 for (var i = ranges.length; i--;) {
13349 var range = ranges[i];
13350 if (!range.isEmpty())
13351 this.session.remove(range);
13352
13353 this.session.insert(range.start, lines[i]);
13354 }
13355 }
13356 };
13357
13358 this.execCommand = function(command, args) {
13359 return this.commands.exec(command, this, args);
13360 };
13361 this.insert = function(text, pasted) {
13362 var session = this.session;
13363 var mode = session.getMode();
13364 var cursor = this.getCursorPosition();
13365
13366 if (this.getBehavioursEnabled() && !pasted) {
13367 var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
13368 if (transform) {
13369 if (text !== transform.text) {
13370 this.session.mergeUndoDeltas = false;
13371 this.$mergeNextCommand = false;
13372 }
13373 text = transform.text;
13374
13375 }
13376 }
13377
13378 if (text == "\t")
13379 text = this.session.getTabString();
13380 if (!this.selection.isEmpty()) {
13381 var range = this.getSelectionRange();
13382 cursor = this.session.remove(range);
13383 this.clearSelection();
13384 }
13385 else if (this.session.getOverwrite() && text.indexOf("\n") == -1) {
13386 var range = new Range.fromPoints(cursor, cursor);
13387 range.end.column += text.length;
13388 this.session.remove(range);
13389 }
13390
13391 if (text == "\n" || text == "\r\n") {
13392 var line = session.getLine(cursor.row);
13393 if (cursor.column > line.search(/\S|$/)) {
13394 var d = line.substr(cursor.column).search(/\S|$/);
13395 session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
13396 }
13397 }
13398 this.clearSelection();
13399
13400 var start = cursor.column;
13401 var lineState = session.getState(cursor.row);
13402 var line = session.getLine(cursor.row);
13403 var shouldOutdent = mode.checkOutdent(lineState, line, text);
13404 session.insert(cursor, text);
13405
13406 if (transform && transform.selection) {
13407 if (transform.selection.length == 2) { // Transform relative to the current column
13408 this.selection.setSelectionRange(
13409 new Range(cursor.row, start + transform.selection[0],
13410 cursor.row, start + transform.selection[1]));
13411 } else { // Transform relative to the current row.
13412 this.selection.setSelectionRange(
13413 new Range(cursor.row + transform.selection[0],
13414 transform.selection[1],
13415 cursor.row + transform.selection[2],
13416 transform.selection[3]));
13417 }
13418 }
13419
13420 if (session.getDocument().isNewLine(text)) {
13421 var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
13422
13423 session.insert({row: cursor.row+1, column: 0}, lineIndent);
13424 }
13425 if (shouldOutdent)
13426 mode.autoOutdent(lineState, session, cursor.row);
13427 };
13428
13429 this.onTextInput = function(text) {
13430 this.keyBinding.onTextInput(text);
13431 };
13432
13433 this.onCommandKey = function(e, hashId, keyCode) {
13434 this.keyBinding.onCommandKey(e, hashId, keyCode);
13435 };
13436 this.setOverwrite = function(overwrite) {
13437 this.session.setOverwrite(overwrite);
13438 };
13439 this.getOverwrite = function() {
13440 return this.session.getOverwrite();
13441 };
13442 this.toggleOverwrite = function() {
13443 this.session.toggleOverwrite();
13444 };
13445 this.setScrollSpeed = function(speed) {
13446 this.setOption("scrollSpeed", speed);
13447 };
13448 this.getScrollSpeed = function() {
13449 return this.getOption("scrollSpeed");
13450 };
13451 this.setDragDelay = function(dragDelay) {
13452 this.setOption("dragDelay", dragDelay);
13453 };
13454 this.getDragDelay = function() {
13455 return this.getOption("dragDelay");
13456 };
13457 this.setSelectionStyle = function(val) {
13458 this.setOption("selectionStyle", val);
13459 };
13460 this.getSelectionStyle = function() {
13461 return this.getOption("selectionStyle");
13462 };
13463 this.setHighlightActiveLine = function(shouldHighlight) {
13464 this.setOption("highlightActiveLine", shouldHighlight);
13465 };
13466 this.getHighlightActiveLine = function() {
13467 return this.getOption("highlightActiveLine");
13468 };
13469 this.setHighlightGutterLine = function(shouldHighlight) {
13470 this.setOption("highlightGutterLine", shouldHighlight);
13471 };
13472
13473 this.getHighlightGutterLine = function() {
13474 return this.getOption("highlightGutterLine");
13475 };
13476 this.setHighlightSelectedWord = function(shouldHighlight) {
13477 this.setOption("highlightSelectedWord", shouldHighlight);
13478 };
13479 this.getHighlightSelectedWord = function() {
13480 return this.$highlightSelectedWord;
13481 };
13482
13483 this.setAnimatedScroll = function(shouldAnimate){
13484 this.renderer.setAnimatedScroll(shouldAnimate);
13485 };
13486
13487 this.getAnimatedScroll = function(){
13488 return this.renderer.getAnimatedScroll();
13489 };
13490 this.setShowInvisibles = function(showInvisibles) {
13491 this.renderer.setShowInvisibles(showInvisibles);
13492 };
13493 this.getShowInvisibles = function() {
13494 return this.renderer.getShowInvisibles();
13495 };
13496
13497 this.setDisplayIndentGuides = function(display) {
13498 this.renderer.setDisplayIndentGuides(display);
13499 };
13500
13501 this.getDisplayIndentGuides = function() {
13502 return this.renderer.getDisplayIndentGuides();
13503 };
13504 this.setShowPrintMargin = function(showPrintMargin) {
13505 this.renderer.setShowPrintMargin(showPrintMargin);
13506 };
13507 this.getShowPrintMargin = function() {
13508 return this.renderer.getShowPrintMargin();
13509 };
13510 this.setPrintMarginColumn = function(showPrintMargin) {
13511 this.renderer.setPrintMarginColumn(showPrintMargin);
13512 };
13513 this.getPrintMarginColumn = function() {
13514 return this.renderer.getPrintMarginColumn();
13515 };
13516 this.setReadOnly = function(readOnly) {
13517 this.setOption("readOnly", readOnly);
13518 };
13519 this.getReadOnly = function() {
13520 return this.getOption("readOnly");
13521 };
13522 this.setBehavioursEnabled = function (enabled) {
13523 this.setOption("behavioursEnabled", enabled);
13524 };
13525 this.getBehavioursEnabled = function () {
13526 return this.getOption("behavioursEnabled");
13527 };
13528 this.setWrapBehavioursEnabled = function (enabled) {
13529 this.setOption("wrapBehavioursEnabled", enabled);
13530 };
13531 this.getWrapBehavioursEnabled = function () {
13532 return this.getOption("wrapBehavioursEnabled");
13533 };
13534 this.setShowFoldWidgets = function(show) {
13535 this.setOption("showFoldWidgets", show);
13536
13537 };
13538 this.getShowFoldWidgets = function() {
13539 return this.getOption("showFoldWidgets");
13540 };
13541
13542 this.setFadeFoldWidgets = function(fade) {
13543 this.setOption("fadeFoldWidgets", fade);
13544 };
13545
13546 this.getFadeFoldWidgets = function() {
13547 return this.getOption("fadeFoldWidgets");
13548 };
13549 this.remove = function(dir) {
13550 if (this.selection.isEmpty()){
13551 if (dir == "left")
13552 this.selection.selectLeft();
13553 else
13554 this.selection.selectRight();
13555 }
13556
13557 var range = this.getSelectionRange();
13558 if (this.getBehavioursEnabled()) {
13559 var session = this.session;
13560 var state = session.getState(range.start.row);
13561 var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
13562
13563 if (range.end.column === 0) {
13564 var text = session.getTextRange(range);
13565 if (text[text.length - 1] == "\n") {
13566 var line = session.getLine(range.end.row);
13567 if (/^\s+$/.test(line)) {
13568 range.end.column = line.length;
13569 }
13570 }
13571 }
13572 if (new_range)
13573 range = new_range;
13574 }
13575
13576 this.session.remove(range);
13577 this.clearSelection();
13578 };
13579 this.removeWordRight = function() {
13580 if (this.selection.isEmpty())
13581 this.selection.selectWordRight();
13582
13583 this.session.remove(this.getSelectionRange());
13584 this.clearSelection();
13585 };
13586 this.removeWordLeft = function() {
13587 if (this.selection.isEmpty())
13588 this.selection.selectWordLeft();
13589
13590 this.session.remove(this.getSelectionRange());
13591 this.clearSelection();
13592 };
13593 this.removeToLineStart = function() {
13594 if (this.selection.isEmpty())
13595 this.selection.selectLineStart();
13596
13597 this.session.remove(this.getSelectionRange());
13598 this.clearSelection();
13599 };
13600 this.removeToLineEnd = function() {
13601 if (this.selection.isEmpty())
13602 this.selection.selectLineEnd();
13603
13604 var range = this.getSelectionRange();
13605 if (range.start.column == range.end.column && range.start.row == range.end.row) {
13606 range.end.column = 0;
13607 range.end.row++;
13608 }
13609
13610 this.session.remove(range);
13611 this.clearSelection();
13612 };
13613 this.splitLine = function() {
13614 if (!this.selection.isEmpty()) {
13615 this.session.remove(this.getSelectionRange());
13616 this.clearSelection();
13617 }
13618
13619 var cursor = this.getCursorPosition();
13620 this.insert("\n");
13621 this.moveCursorToPosition(cursor);
13622 };
13623 this.transposeLetters = function() {
13624 if (!this.selection.isEmpty()) {
13625 return;
13626 }
13627
13628 var cursor = this.getCursorPosition();
13629 var column = cursor.column;
13630 if (column === 0)
13631 return;
13632
13633 var line = this.session.getLine(cursor.row);
13634 var swap, range;
13635 if (column < line.length) {
13636 swap = line.charAt(column) + line.charAt(column-1);
13637 range = new Range(cursor.row, column-1, cursor.row, column+1);
13638 }
13639 else {
13640 swap = line.charAt(column-1) + line.charAt(column-2);
13641 range = new Range(cursor.row, column-2, cursor.row, column);
13642 }
13643 this.session.replace(range, swap);
13644 this.session.selection.moveToPosition(range.end);
13645 };
13646 this.toLowerCase = function() {
13647 var originalRange = this.getSelectionRange();
13648 if (this.selection.isEmpty()) {
13649 this.selection.selectWord();
13650 }
13651
13652 var range = this.getSelectionRange();
13653 var text = this.session.getTextRange(range);
13654 this.session.replace(range, text.toLowerCase());
13655 this.selection.setSelectionRange(originalRange);
13656 };
13657 this.toUpperCase = function() {
13658 var originalRange = this.getSelectionRange();
13659 if (this.selection.isEmpty()) {
13660 this.selection.selectWord();
13661 }
13662
13663 var range = this.getSelectionRange();
13664 var text = this.session.getTextRange(range);
13665 this.session.replace(range, text.toUpperCase());
13666 this.selection.setSelectionRange(originalRange);
13667 };
13668 this.indent = function() {
13669 var session = this.session;
13670 var range = this.getSelectionRange();
13671
13672 if (range.start.row < range.end.row) {
13673 var rows = this.$getSelectedRows();
13674 session.indentRows(rows.first, rows.last, "\t");
13675 return;
13676 } else if (range.start.column < range.end.column) {
13677 var text = session.getTextRange(range);
13678 if (!/^\s+$/.test(text)) {
13679 var rows = this.$getSelectedRows();
13680 session.indentRows(rows.first, rows.last, "\t");
13681 return;
13682 }
13683 }
13684
13685 var line = session.getLine(range.start.row);
13686 var position = range.start;
13687 var size = session.getTabSize();
13688 var column = session.documentToScreenColumn(position.row, position.column);
13689
13690 if (this.session.getUseSoftTabs()) {
13691 var count = (size - column % size);
13692 var indentString = lang.stringRepeat(" ", count);
13693 } else {
13694 var count = column % size;
13695 while (line[range.start.column - 1] == " " && count) {
13696 range.start.column--;
13697 count--;
13698 }
13699 this.selection.setSelectionRange(range);
13700 indentString = "\t";
13701 }
13702 return this.insert(indentString);
13703 };
13704 this.blockIndent = function() {
13705 var rows = this.$getSelectedRows();
13706 this.session.indentRows(rows.first, rows.last, "\t");
13707 };
13708 this.blockOutdent = function() {
13709 var selection = this.session.getSelection();
13710 this.session.outdentRows(selection.getRange());
13711 };
13712 this.sortLines = function() {
13713 var rows = this.$getSelectedRows();
13714 var session = this.session;
13715
13716 var lines = [];
13717 for (var i = rows.first; i <= rows.last; i++)
13718 lines.push(session.getLine(i));
13719
13720 lines.sort(function(a, b) {
13721 if (a.toLowerCase() < b.toLowerCase()) return -1;
13722 if (a.toLowerCase() > b.toLowerCase()) return 1;
13723 return 0;
13724 });
13725
13726 var deleteRange = new Range(0, 0, 0, 0);
13727 for (var i = rows.first; i <= rows.last; i++) {
13728 var line = session.getLine(i);
13729 deleteRange.start.row = i;
13730 deleteRange.end.row = i;
13731 deleteRange.end.column = line.length;
13732 session.replace(deleteRange, lines[i-rows.first]);
13733 }
13734 };
13735 this.toggleCommentLines = function() {
13736 var state = this.session.getState(this.getCursorPosition().row);
13737 var rows = this.$getSelectedRows();
13738 this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
13739 };
13740
13741 this.toggleBlockComment = function() {
13742 var cursor = this.getCursorPosition();
13743 var state = this.session.getState(cursor.row);
13744 var range = this.getSelectionRange();
13745 this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
13746 };
13747 this.getNumberAt = function(row, column) {
13748 var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
13749 _numberRx.lastIndex = 0;
13750
13751 var s = this.session.getLine(row);
13752 while (_numberRx.lastIndex < column) {
13753 var m = _numberRx.exec(s);
13754 if(m.index <= column && m.index+m[0].length >= column){
13755 var number = {
13756 value: m[0],
13757 start: m.index,
13758 end: m.index+m[0].length
13759 };
13760 return number;
13761 }
13762 }
13763 return null;
13764 };
13765 this.modifyNumber = function(amount) {
13766 var row = this.selection.getCursor().row;
13767 var column = this.selection.getCursor().column;
13768 var charRange = new Range(row, column-1, row, column);
13769
13770 var c = this.session.getTextRange(charRange);
13771 if (!isNaN(parseFloat(c)) && isFinite(c)) {
13772 var nr = this.getNumberAt(row, column);
13773 if (nr) {
13774 var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
13775 var decimals = nr.start + nr.value.length - fp;
13776
13777 var t = parseFloat(nr.value);
13778 t *= Math.pow(10, decimals);
13779
13780
13781 if(fp !== nr.end && column < fp){
13782 amount *= Math.pow(10, nr.end - column - 1);
13783 } else {
13784 amount *= Math.pow(10, nr.end - column);
13785 }
13786
13787 t += amount;
13788 t /= Math.pow(10, decimals);
13789 var nnr = t.toFixed(decimals);
13790 var replaceRange = new Range(row, nr.start, row, nr.end);
13791 this.session.replace(replaceRange, nnr);
13792 this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
13793
13794 }
13795 }
13796 };
13797 this.removeLines = function() {
13798 var rows = this.$getSelectedRows();
13799 this.session.removeFullLines(rows.first, rows.last);
13800 this.clearSelection();
13801 };
13802
13803 this.duplicateSelection = function() {
13804 var sel = this.selection;
13805 var doc = this.session;
13806 var range = sel.getRange();
13807 var reverse = sel.isBackwards();
13808 if (range.isEmpty()) {
13809 var row = range.start.row;
13810 doc.duplicateLines(row, row);
13811 } else {
13812 var point = reverse ? range.start : range.end;
13813 var endPoint = doc.insert(point, doc.getTextRange(range), false);
13814 range.start = point;
13815 range.end = endPoint;
13816
13817 sel.setSelectionRange(range, reverse);
13818 }
13819 };
13820 this.moveLinesDown = function() {
13821 this.$moveLines(1, false);
13822 };
13823 this.moveLinesUp = function() {
13824 this.$moveLines(-1, false);
13825 };
13826 this.moveText = function(range, toPosition, copy) {
13827 return this.session.moveText(range, toPosition, copy);
13828 };
13829 this.copyLinesUp = function() {
13830 this.$moveLines(-1, true);
13831 };
13832 this.copyLinesDown = function() {
13833 this.$moveLines(1, true);
13834 };
13835 this.$moveLines = function(dir, copy) {
13836 var rows, moved;
13837 var selection = this.selection;
13838 if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
13839 var range = selection.toOrientedRange();
13840 rows = this.$getSelectedRows(range);
13841 moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
13842 if (copy && dir == -1) moved = 0;
13843 range.moveBy(moved, 0);
13844 selection.fromOrientedRange(range);
13845 } else {
13846 var ranges = selection.rangeList.ranges;
13847 selection.rangeList.detach(this.session);
13848 this.inVirtualSelectionMode = true;
13849
13850 var diff = 0;
13851 var totalDiff = 0;
13852 var l = ranges.length;
13853 for (var i = 0; i < l; i++) {
13854 var rangeIndex = i;
13855 ranges[i].moveBy(diff, 0);
13856 rows = this.$getSelectedRows(ranges[i]);
13857 var first = rows.first;
13858 var last = rows.last;
13859 while (++i < l) {
13860 if (totalDiff) ranges[i].moveBy(totalDiff, 0);
13861 var subRows = this.$getSelectedRows(ranges[i]);
13862 if (copy && subRows.first != last)
13863 break;
13864 else if (!copy && subRows.first > last + 1)
13865 break;
13866 last = subRows.last;
13867 }
13868 i--;
13869 diff = this.session.$moveLines(first, last, copy ? 0 : dir);
13870 if (copy && dir == -1) rangeIndex = i + 1;
13871 while (rangeIndex <= i) {
13872 ranges[rangeIndex].moveBy(diff, 0);
13873 rangeIndex++;
13874 }
13875 if (!copy) diff = 0;
13876 totalDiff += diff;
13877 }
13878
13879 selection.fromOrientedRange(selection.ranges[0]);
13880 selection.rangeList.attach(this.session);
13881 this.inVirtualSelectionMode = false;
13882 }
13883 };
13884 this.$getSelectedRows = function(range) {
13885 range = (range || this.getSelectionRange()).collapseRows();
13886
13887 return {
13888 first: this.session.getRowFoldStart(range.start.row),
13889 last: this.session.getRowFoldEnd(range.end.row)
13890 };
13891 };
13892
13893 this.onCompositionStart = function(text) {
13894 this.renderer.showComposition(this.getCursorPosition());
13895 };
13896
13897 this.onCompositionUpdate = function(text) {
13898 this.renderer.setCompositionText(text);
13899 };
13900
13901 this.onCompositionEnd = function() {
13902 this.renderer.hideComposition();
13903 };
13904 this.getFirstVisibleRow = function() {
13905 return this.renderer.getFirstVisibleRow();
13906 };
13907 this.getLastVisibleRow = function() {
13908 return this.renderer.getLastVisibleRow();
13909 };
13910 this.isRowVisible = function(row) {
13911 return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
13912 };
13913 this.isRowFullyVisible = function(row) {
13914 return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
13915 };
13916 this.$getVisibleRowCount = function() {
13917 return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
13918 };
13919
13920 this.$moveByPage = function(dir, select) {
13921 var renderer = this.renderer;
13922 var config = this.renderer.layerConfig;
13923 var rows = dir * Math.floor(config.height / config.lineHeight);
13924
13925 this.$blockScrolling++;
13926 if (select === true) {
13927 this.selection.$moveSelection(function(){
13928 this.moveCursorBy(rows, 0);
13929 });
13930 } else if (select === false) {
13931 this.selection.moveCursorBy(rows, 0);
13932 this.selection.clearSelection();
13933 }
13934 this.$blockScrolling--;
13935
13936 var scrollTop = renderer.scrollTop;
13937
13938 renderer.scrollBy(0, rows * config.lineHeight);
13939 if (select != null)
13940 renderer.scrollCursorIntoView(null, 0.5);
13941
13942 renderer.animateScrolling(scrollTop);
13943 };
13944 this.selectPageDown = function() {
13945 this.$moveByPage(1, true);
13946 };
13947 this.selectPageUp = function() {
13948 this.$moveByPage(-1, true);
13949 };
13950 this.gotoPageDown = function() {
13951 this.$moveByPage(1, false);
13952 };
13953 this.gotoPageUp = function() {
13954 this.$moveByPage(-1, false);
13955 };
13956 this.scrollPageDown = function() {
13957 this.$moveByPage(1);
13958 };
13959 this.scrollPageUp = function() {
13960 this.$moveByPage(-1);
13961 };
13962 this.scrollToRow = function(row) {
13963 this.renderer.scrollToRow(row);
13964 };
13965 this.scrollToLine = function(line, center, animate, callback) {
13966 this.renderer.scrollToLine(line, center, animate, callback);
13967 };
13968 this.centerSelection = function() {
13969 var range = this.getSelectionRange();
13970 var pos = {
13971 row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
13972 column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
13973 };
13974 this.renderer.alignCursor(pos, 0.5);
13975 };
13976 this.getCursorPosition = function() {
13977 return this.selection.getCursor();
13978 };
13979 this.getCursorPositionScreen = function() {
13980 return this.session.documentToScreenPosition(this.getCursorPosition());
13981 };
13982 this.getSelectionRange = function() {
13983 return this.selection.getRange();
13984 };
13985 this.selectAll = function() {
13986 this.$blockScrolling += 1;
13987 this.selection.selectAll();
13988 this.$blockScrolling -= 1;
13989 };
13990 this.clearSelection = function() {
13991 this.selection.clearSelection();
13992 };
13993 this.moveCursorTo = function(row, column) {
13994 this.selection.moveCursorTo(row, column);
13995 };
13996 this.moveCursorToPosition = function(pos) {
13997 this.selection.moveCursorToPosition(pos);
13998 };
13999 this.jumpToMatching = function(select, expand) {
14000 var cursor = this.getCursorPosition();
14001 var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
14002 var prevToken = iterator.getCurrentToken();
14003 var token = prevToken || iterator.stepForward();
14004
14005 if (!token) return;
14006 var matchType;
14007 var found = false;
14008 var depth = {};
14009 var i = cursor.column - token.start;
14010 var bracketType;
14011 var brackets = {
14012 ")": "(",
14013 "(": "(",
14014 "]": "[",
14015 "[": "[",
14016 "{": "{",
14017 "}": "{"
14018 };
14019
14020 do {
14021 if (token.value.match(/[{}()\[\]]/g)) {
14022 for (; i < token.value.length && !found; i++) {
14023 if (!brackets[token.value[i]]) {
14024 continue;
14025 }
14026
14027 bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
14028
14029 if (isNaN(depth[bracketType])) {
14030 depth[bracketType] = 0;
14031 }
14032
14033 switch (token.value[i]) {
14034 case '(':
14035 case '[':
14036 case '{':
14037 depth[bracketType]++;
14038 break;
14039 case ')':
14040 case ']':
14041 case '}':
14042 depth[bracketType]--;
14043
14044 if (depth[bracketType] === -1) {
14045 matchType = 'bracket';
14046 found = true;
14047 }
14048 break;
14049 }
14050 }
14051 }
14052 else if (token && token.type.indexOf('tag-name') !== -1) {
14053 if (isNaN(depth[token.value])) {
14054 depth[token.value] = 0;
14055 }
14056
14057 if (prevToken.value === '<') {
14058 depth[token.value]++;
14059 }
14060 else if (prevToken.value === '</') {
14061 depth[token.value]--;
14062 }
14063
14064 if (depth[token.value] === -1) {
14065 matchType = 'tag';
14066 found = true;
14067 }
14068 }
14069
14070 if (!found) {
14071 prevToken = token;
14072 token = iterator.stepForward();
14073 i = 0;
14074 }
14075 } while (token && !found);
14076 if (!matchType)
14077 return;
14078
14079 var range, pos;
14080 if (matchType === 'bracket') {
14081 range = this.session.getBracketRange(cursor);
14082 if (!range) {
14083 range = new Range(
14084 iterator.getCurrentTokenRow(),
14085 iterator.getCurrentTokenColumn() + i - 1,
14086 iterator.getCurrentTokenRow(),
14087 iterator.getCurrentTokenColumn() + i - 1
14088 );
14089 pos = range.start;
14090 if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)
14091 range = this.session.getBracketRange(pos);
14092 }
14093 }
14094 else if (matchType === 'tag') {
14095 if (token && token.type.indexOf('tag-name') !== -1)
14096 var tag = token.value;
14097 else
14098 return;
14099
14100 range = new Range(
14101 iterator.getCurrentTokenRow(),
14102 iterator.getCurrentTokenColumn() - 2,
14103 iterator.getCurrentTokenRow(),
14104 iterator.getCurrentTokenColumn() - 2
14105 );
14106 if (range.compare(cursor.row, cursor.column) === 0) {
14107 found = false;
14108 do {
14109 token = prevToken;
14110 prevToken = iterator.stepBackward();
14111
14112 if (prevToken) {
14113 if (prevToken.type.indexOf('tag-close') !== -1) {
14114 range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);
14115 }
14116
14117 if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
14118 if (prevToken.value === '<') {
14119 depth[tag]++;
14120 }
14121 else if (prevToken.value === '</') {
14122 depth[tag]--;
14123 }
14124
14125 if (depth[tag] === 0)
14126 found = true;
14127 }
14128 }
14129 } while (prevToken && !found);
14130 }
14131 if (token && token.type.indexOf('tag-name')) {
14132 pos = range.start;
14133 if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
14134 pos = range.end;
14135 }
14136 }
14137
14138 pos = range && range.cursor || pos;
14139 if (pos) {
14140 if (select) {
14141 if (range && expand) {
14142 this.selection.setRange(range);
14143 } else if (range && range.isEqual(this.getSelectionRange())) {
14144 this.clearSelection();
14145 } else {
14146 this.selection.selectTo(pos.row, pos.column);
14147 }
14148 } else {
14149 this.selection.moveTo(pos.row, pos.column);
14150 }
14151 }
14152 };
14153 this.gotoLine = function(lineNumber, column, animate) {
14154 this.selection.clearSelection();
14155 this.session.unfold({row: lineNumber - 1, column: column || 0});
14156
14157 this.$blockScrolling += 1;
14158 this.exitMultiSelectMode && this.exitMultiSelectMode();
14159 this.moveCursorTo(lineNumber - 1, column || 0);
14160 this.$blockScrolling -= 1;
14161
14162 if (!this.isRowFullyVisible(lineNumber - 1))
14163 this.scrollToLine(lineNumber - 1, true, animate);
14164 };
14165 this.navigateTo = function(row, column) {
14166 this.selection.moveTo(row, column);
14167 };
14168 this.navigateUp = function(times) {
14169 if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
14170 var selectionStart = this.selection.anchor.getPosition();
14171 return this.moveCursorToPosition(selectionStart);
14172 }
14173 this.selection.clearSelection();
14174 this.selection.moveCursorBy(-times || -1, 0);
14175 };
14176 this.navigateDown = function(times) {
14177 if (this.selection.isMultiLine() && this.selection.isBackwards()) {
14178 var selectionEnd = this.selection.anchor.getPosition();
14179 return this.moveCursorToPosition(selectionEnd);
14180 }
14181 this.selection.clearSelection();
14182 this.selection.moveCursorBy(times || 1, 0);
14183 };
14184 this.navigateLeft = function(times) {
14185 if (!this.selection.isEmpty()) {
14186 var selectionStart = this.getSelectionRange().start;
14187 this.moveCursorToPosition(selectionStart);
14188 }
14189 else {
14190 times = times || 1;
14191 while (times--) {
14192 this.selection.moveCursorLeft();
14193 }
14194 }
14195 this.clearSelection();
14196 };
14197 this.navigateRight = function(times) {
14198 if (!this.selection.isEmpty()) {
14199 var selectionEnd = this.getSelectionRange().end;
14200 this.moveCursorToPosition(selectionEnd);
14201 }
14202 else {
14203 times = times || 1;
14204 while (times--) {
14205 this.selection.moveCursorRight();
14206 }
14207 }
14208 this.clearSelection();
14209 };
14210 this.navigateLineStart = function() {
14211 this.selection.moveCursorLineStart();
14212 this.clearSelection();
14213 };
14214 this.navigateLineEnd = function() {
14215 this.selection.moveCursorLineEnd();
14216 this.clearSelection();
14217 };
14218 this.navigateFileEnd = function() {
14219 this.selection.moveCursorFileEnd();
14220 this.clearSelection();
14221 };
14222 this.navigateFileStart = function() {
14223 this.selection.moveCursorFileStart();
14224 this.clearSelection();
14225 };
14226 this.navigateWordRight = function() {
14227 this.selection.moveCursorWordRight();
14228 this.clearSelection();
14229 };
14230 this.navigateWordLeft = function() {
14231 this.selection.moveCursorWordLeft();
14232 this.clearSelection();
14233 };
14234 this.replace = function(replacement, options) {
14235 if (options)
14236 this.$search.set(options);
14237
14238 var range = this.$search.find(this.session);
14239 var replaced = 0;
14240 if (!range)
14241 return replaced;
14242
14243 if (this.$tryReplace(range, replacement)) {
14244 replaced = 1;
14245 }
14246 if (range !== null) {
14247 this.selection.setSelectionRange(range);
14248 this.renderer.scrollSelectionIntoView(range.start, range.end);
14249 }
14250
14251 return replaced;
14252 };
14253 this.replaceAll = function(replacement, options) {
14254 if (options) {
14255 this.$search.set(options);
14256 }
14257
14258 var ranges = this.$search.findAll(this.session);
14259 var replaced = 0;
14260 if (!ranges.length)
14261 return replaced;
14262
14263 this.$blockScrolling += 1;
14264
14265 var selection = this.getSelectionRange();
14266 this.selection.moveTo(0, 0);
14267
14268 for (var i = ranges.length - 1; i >= 0; --i) {
14269 if(this.$tryReplace(ranges[i], replacement)) {
14270 replaced++;
14271 }
14272 }
14273
14274 this.selection.setSelectionRange(selection);
14275 this.$blockScrolling -= 1;
14276
14277 return replaced;
14278 };
14279
14280 this.$tryReplace = function(range, replacement) {
14281 var input = this.session.getTextRange(range);
14282 replacement = this.$search.replace(input, replacement);
14283 if (replacement !== null) {
14284 range.end = this.session.replace(range, replacement);
14285 return range;
14286 } else {
14287 return null;
14288 }
14289 };
14290 this.getLastSearchOptions = function() {
14291 return this.$search.getOptions();
14292 };
14293 this.find = function(needle, options, animate) {
14294 if (!options)
14295 options = {};
14296
14297 if (typeof needle == "string" || needle instanceof RegExp)
14298 options.needle = needle;
14299 else if (typeof needle == "object")
14300 oop.mixin(options, needle);
14301
14302 var range = this.selection.getRange();
14303 if (options.needle == null) {
14304 needle = this.session.getTextRange(range)
14305 || this.$search.$options.needle;
14306 if (!needle) {
14307 range = this.session.getWordRange(range.start.row, range.start.column);
14308 needle = this.session.getTextRange(range);
14309 }
14310 this.$search.set({needle: needle});
14311 }
14312
14313 this.$search.set(options);
14314 if (!options.start)
14315 this.$search.set({start: range});
14316
14317 var newRange = this.$search.find(this.session);
14318 if (options.preventScroll)
14319 return newRange;
14320 if (newRange) {
14321 this.revealRange(newRange, animate);
14322 return newRange;
14323 }
14324 if (options.backwards)
14325 range.start = range.end;
14326 else
14327 range.end = range.start;
14328 this.selection.setRange(range);
14329 };
14330 this.findNext = function(options, animate) {
14331 this.find({skipCurrent: true, backwards: false}, options, animate);
14332 };
14333 this.findPrevious = function(options, animate) {
14334 this.find(options, {skipCurrent: true, backwards: true}, animate);
14335 };
14336
14337 this.revealRange = function(range, animate) {
14338 this.$blockScrolling += 1;
14339 this.session.unfold(range);
14340 this.selection.setSelectionRange(range);
14341 this.$blockScrolling -= 1;
14342
14343 var scrollTop = this.renderer.scrollTop;
14344 this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
14345 if (animate !== false)
14346 this.renderer.animateScrolling(scrollTop);
14347 };
14348 this.undo = function() {
14349 this.$blockScrolling++;
14350 this.session.getUndoManager().undo();
14351 this.$blockScrolling--;
14352 this.renderer.scrollCursorIntoView(null, 0.5);
14353 };
14354 this.redo = function() {
14355 this.$blockScrolling++;
14356 this.session.getUndoManager().redo();
14357 this.$blockScrolling--;
14358 this.renderer.scrollCursorIntoView(null, 0.5);
14359 };
14360 this.destroy = function() {
14361 this.renderer.destroy();
14362 this._signal("destroy", this);
14363 if (this.session) {
14364 this.session.destroy();
14365 }
14366 };
14367 this.setAutoScrollEditorIntoView = function(enable) {
14368 if (!enable)
14369 return;
14370 var rect;
14371 var self = this;
14372 var shouldScroll = false;
14373 if (!this.$scrollAnchor)
14374 this.$scrollAnchor = document.createElement("div");
14375 var scrollAnchor = this.$scrollAnchor;
14376 scrollAnchor.style.cssText = "position:absolute";
14377 this.container.insertBefore(scrollAnchor, this.container.firstChild);
14378 var onChangeSelection = this.on("changeSelection", function() {
14379 shouldScroll = true;
14380 });
14381 var onBeforeRender = this.renderer.on("beforeRender", function() {
14382 if (shouldScroll)
14383 rect = self.renderer.container.getBoundingClientRect();
14384 });
14385 var onAfterRender = this.renderer.on("afterRender", function() {
14386 if (shouldScroll && rect && (self.isFocused()
14387 || self.searchBox && self.searchBox.isFocused())
14388 ) {
14389 var renderer = self.renderer;
14390 var pos = renderer.$cursorLayer.$pixelPos;
14391 var config = renderer.layerConfig;
14392 var top = pos.top - config.offset;
14393 if (pos.top >= 0 && top + rect.top < 0) {
14394 shouldScroll = true;
14395 } else if (pos.top < config.height &&
14396 pos.top + rect.top + config.lineHeight > window.innerHeight) {
14397 shouldScroll = false;
14398 } else {
14399 shouldScroll = null;
14400 }
14401 if (shouldScroll != null) {
14402 scrollAnchor.style.top = top + "px";
14403 scrollAnchor.style.left = pos.left + "px";
14404 scrollAnchor.style.height = config.lineHeight + "px";
14405 scrollAnchor.scrollIntoView(shouldScroll);
14406 }
14407 shouldScroll = rect = null;
14408 }
14409 });
14410 this.setAutoScrollEditorIntoView = function(enable) {
14411 if (enable)
14412 return;
14413 delete this.setAutoScrollEditorIntoView;
14414 this.off("changeSelection", onChangeSelection);
14415 this.renderer.off("afterRender", onAfterRender);
14416 this.renderer.off("beforeRender", onBeforeRender);
14417 };
14418 };
14419
14420
14421 this.$resetCursorStyle = function() {
14422 var style = this.$cursorStyle || "ace";
14423 var cursorLayer = this.renderer.$cursorLayer;
14424 if (!cursorLayer)
14425 return;
14426 cursorLayer.setSmoothBlinking(/smooth/.test(style));
14427 cursorLayer.isBlinking = !this.$readOnly && style != "wide";
14428 dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
14429 };
14430
14431}).call(Editor.prototype);
14432
14433
14434
14435config.defineOptions(Editor.prototype, "editor", {
14436 selectionStyle: {
14437 set: function(style) {
14438 this.onSelectionChange();
14439 this._signal("changeSelectionStyle", {data: style});
14440 },
14441 initialValue: "line"
14442 },
14443 highlightActiveLine: {
14444 set: function() {this.$updateHighlightActiveLine();},
14445 initialValue: true
14446 },
14447 highlightSelectedWord: {
14448 set: function(shouldHighlight) {this.$onSelectionChange();},
14449 initialValue: true
14450 },
14451 readOnly: {
14452 set: function(readOnly) {
14453 this.$resetCursorStyle();
14454 },
14455 initialValue: false
14456 },
14457 cursorStyle: {
14458 set: function(val) { this.$resetCursorStyle(); },
14459 values: ["ace", "slim", "smooth", "wide"],
14460 initialValue: "ace"
14461 },
14462 mergeUndoDeltas: {
14463 values: [false, true, "always"],
14464 initialValue: true
14465 },
14466 behavioursEnabled: {initialValue: true},
14467 wrapBehavioursEnabled: {initialValue: true},
14468 autoScrollEditorIntoView: {
14469 set: function(val) {this.setAutoScrollEditorIntoView(val);}
14470 },
14471 keyboardHandler: {
14472 set: function(val) { this.setKeyboardHandler(val); },
14473 get: function() { return this.keybindingId; },
14474 handlesSet: true
14475 },
14476
14477 hScrollBarAlwaysVisible: "renderer",
14478 vScrollBarAlwaysVisible: "renderer",
14479 highlightGutterLine: "renderer",
14480 animatedScroll: "renderer",
14481 showInvisibles: "renderer",
14482 showPrintMargin: "renderer",
14483 printMarginColumn: "renderer",
14484 printMargin: "renderer",
14485 fadeFoldWidgets: "renderer",
14486 showFoldWidgets: "renderer",
14487 showLineNumbers: "renderer",
14488 showGutter: "renderer",
14489 displayIndentGuides: "renderer",
14490 fontSize: "renderer",
14491 fontFamily: "renderer",
14492 maxLines: "renderer",
14493 minLines: "renderer",
14494 scrollPastEnd: "renderer",
14495 fixedWidthGutter: "renderer",
14496 theme: "renderer",
14497
14498 scrollSpeed: "$mouseHandler",
14499 dragDelay: "$mouseHandler",
14500 dragEnabled: "$mouseHandler",
14501 focusTimout: "$mouseHandler",
14502 tooltipFollowsMouse: "$mouseHandler",
14503
14504 firstLineNumber: "session",
14505 overwrite: "session",
14506 newLineMode: "session",
14507 useWorker: "session",
14508 useSoftTabs: "session",
14509 tabSize: "session",
14510 wrap: "session",
14511 indentedSoftWrap: "session",
14512 foldStyle: "session",
14513 mode: "session"
14514});
14515
14516exports.Editor = Editor;
14517});
14518
14519ace.define("ace/undomanager",["require","exports","module"], function(acequire, exports, module) {
14520var UndoManager = function() {
14521 this.reset();
14522};
14523
14524(function() {
14525 this.execute = function(options) {
14526 var deltaSets = options.args[0];
14527 this.$doc = options.args[1];
14528 if (options.merge && this.hasUndo()){
14529 this.dirtyCounter--;
14530 deltaSets = this.$undoStack.pop().concat(deltaSets);
14531 }
14532 this.$undoStack.push(deltaSets);
14533 this.$redoStack = [];
14534 if (this.dirtyCounter < 0) {
14535 this.dirtyCounter = NaN;
14536 }
14537 this.dirtyCounter++;
14538 };
14539 this.undo = function(dontSelect) {
14540 var deltaSets = this.$undoStack.pop();
14541 var undoSelectionRange = null;
14542 if (deltaSets) {
14543 undoSelectionRange = this.$doc.undoChanges(deltaSets, dontSelect);
14544 this.$redoStack.push(deltaSets);
14545 this.dirtyCounter--;
14546 }
14547
14548 return undoSelectionRange;
14549 };
14550 this.redo = function(dontSelect) {
14551 var deltaSets = this.$redoStack.pop();
14552 var redoSelectionRange = null;
14553 if (deltaSets) {
14554 redoSelectionRange =
14555 this.$doc.redoChanges(this.$deserializeDeltas(deltaSets), dontSelect);
14556 this.$undoStack.push(deltaSets);
14557 this.dirtyCounter++;
14558 }
14559 return redoSelectionRange;
14560 };
14561 this.reset = function() {
14562 this.$undoStack = [];
14563 this.$redoStack = [];
14564 this.dirtyCounter = 0;
14565 };
14566 this.hasUndo = function() {
14567 return this.$undoStack.length > 0;
14568 };
14569 this.hasRedo = function() {
14570 return this.$redoStack.length > 0;
14571 };
14572 this.markClean = function() {
14573 this.dirtyCounter = 0;
14574 };
14575 this.isClean = function() {
14576 return this.dirtyCounter === 0;
14577 };
14578 this.$serializeDeltas = function(deltaSets) {
14579 return cloneDeltaSetsObj(deltaSets, $serializeDelta);
14580 };
14581 this.$deserializeDeltas = function(deltaSets) {
14582 return cloneDeltaSetsObj(deltaSets, $deserializeDelta);
14583 };
14584
14585 function $serializeDelta(delta){
14586 return {
14587 action: delta.action,
14588 start: delta.start,
14589 end: delta.end,
14590 lines: delta.lines.length == 1 ? null : delta.lines,
14591 text: delta.lines.length == 1 ? delta.lines[0] : null
14592 };
14593 }
14594
14595 function $deserializeDelta(delta) {
14596 return {
14597 action: delta.action,
14598 start: delta.start,
14599 end: delta.end,
14600 lines: delta.lines || [delta.text]
14601 };
14602 }
14603
14604 function cloneDeltaSetsObj(deltaSets_old, fnGetModifiedDelta) {
14605 var deltaSets_new = new Array(deltaSets_old.length);
14606 for (var i = 0; i < deltaSets_old.length; i++) {
14607 var deltaSet_old = deltaSets_old[i];
14608 var deltaSet_new = { group: deltaSet_old.group, deltas: new Array(deltaSet_old.length)};
14609
14610 for (var j = 0; j < deltaSet_old.deltas.length; j++) {
14611 var delta_old = deltaSet_old.deltas[j];
14612 deltaSet_new.deltas[j] = fnGetModifiedDelta(delta_old);
14613 }
14614
14615 deltaSets_new[i] = deltaSet_new;
14616 }
14617 return deltaSets_new;
14618 }
14619
14620}).call(UndoManager.prototype);
14621
14622exports.UndoManager = UndoManager;
14623});
14624
14625ace.define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"], function(acequire, exports, module) {
14626
14627var dom = acequire("../lib/dom");
14628var oop = acequire("../lib/oop");
14629var lang = acequire("../lib/lang");
14630var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
14631
14632var Gutter = function(parentEl) {
14633 this.element = dom.createElement("div");
14634 this.element.className = "ace_layer ace_gutter-layer";
14635 parentEl.appendChild(this.element);
14636 this.setShowFoldWidgets(this.$showFoldWidgets);
14637
14638 this.gutterWidth = 0;
14639
14640 this.$annotations = [];
14641 this.$updateAnnotations = this.$updateAnnotations.bind(this);
14642
14643 this.$cells = [];
14644};
14645
14646(function() {
14647
14648 oop.implement(this, EventEmitter);
14649
14650 this.setSession = function(session) {
14651 if (this.session)
14652 this.session.removeEventListener("change", this.$updateAnnotations);
14653 this.session = session;
14654 if (session)
14655 session.on("change", this.$updateAnnotations);
14656 };
14657
14658 this.addGutterDecoration = function(row, className){
14659 if (window.console)
14660 console.warn && console.warn("deprecated use session.addGutterDecoration");
14661 this.session.addGutterDecoration(row, className);
14662 };
14663
14664 this.removeGutterDecoration = function(row, className){
14665 if (window.console)
14666 console.warn && console.warn("deprecated use session.removeGutterDecoration");
14667 this.session.removeGutterDecoration(row, className);
14668 };
14669
14670 this.setAnnotations = function(annotations) {
14671 this.$annotations = [];
14672 for (var i = 0; i < annotations.length; i++) {
14673 var annotation = annotations[i];
14674 var row = annotation.row;
14675 var rowInfo = this.$annotations[row];
14676 if (!rowInfo)
14677 rowInfo = this.$annotations[row] = {text: []};
14678
14679 var annoText = annotation.text;
14680 annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || "";
14681
14682 if (rowInfo.text.indexOf(annoText) === -1)
14683 rowInfo.text.push(annoText);
14684
14685 var type = annotation.type;
14686 if (type == "error")
14687 rowInfo.className = " ace_error";
14688 else if (type == "warning" && rowInfo.className != " ace_error")
14689 rowInfo.className = " ace_warning";
14690 else if (type == "info" && (!rowInfo.className))
14691 rowInfo.className = " ace_info";
14692 }
14693 };
14694
14695 this.$updateAnnotations = function (delta) {
14696 if (!this.$annotations.length)
14697 return;
14698 var firstRow = delta.start.row;
14699 var len = delta.end.row - firstRow;
14700 if (len === 0) ; else if (delta.action == 'remove') {
14701 this.$annotations.splice(firstRow, len + 1, null);
14702 } else {
14703 var args = new Array(len + 1);
14704 args.unshift(firstRow, 1);
14705 this.$annotations.splice.apply(this.$annotations, args);
14706 }
14707 };
14708
14709 this.update = function(config) {
14710 var session = this.session;
14711 var firstRow = config.firstRow;
14712 var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar
14713 session.getLength() - 1);
14714 var fold = session.getNextFoldLine(firstRow);
14715 var foldStart = fold ? fold.start.row : Infinity;
14716 var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
14717 var breakpoints = session.$breakpoints;
14718 var decorations = session.$decorations;
14719 var firstLineNumber = session.$firstLineNumber;
14720 var lastLineNumber = 0;
14721
14722 var gutterRenderer = session.gutterRenderer || this.$renderer;
14723
14724 var cell = null;
14725 var index = -1;
14726 var row = firstRow;
14727 while (true) {
14728 if (row > foldStart) {
14729 row = fold.end.row + 1;
14730 fold = session.getNextFoldLine(row, fold);
14731 foldStart = fold ? fold.start.row : Infinity;
14732 }
14733 if (row > lastRow) {
14734 while (this.$cells.length > index + 1) {
14735 cell = this.$cells.pop();
14736 this.element.removeChild(cell.element);
14737 }
14738 break;
14739 }
14740
14741 cell = this.$cells[++index];
14742 if (!cell) {
14743 cell = {element: null, textNode: null, foldWidget: null};
14744 cell.element = dom.createElement("div");
14745 cell.textNode = document.createTextNode('');
14746 cell.element.appendChild(cell.textNode);
14747 this.element.appendChild(cell.element);
14748 this.$cells[index] = cell;
14749 }
14750
14751 var className = "ace_gutter-cell ";
14752 if (breakpoints[row])
14753 className += breakpoints[row];
14754 if (decorations[row])
14755 className += decorations[row];
14756 if (this.$annotations[row])
14757 className += this.$annotations[row].className;
14758 if (cell.element.className != className)
14759 cell.element.className = className;
14760
14761 var height = session.getRowLength(row) * config.lineHeight + "px";
14762 if (height != cell.element.style.height)
14763 cell.element.style.height = height;
14764
14765 if (foldWidgets) {
14766 var c = foldWidgets[row];
14767 if (c == null)
14768 c = foldWidgets[row] = session.getFoldWidget(row);
14769 }
14770
14771 if (c) {
14772 if (!cell.foldWidget) {
14773 cell.foldWidget = dom.createElement("span");
14774 cell.element.appendChild(cell.foldWidget);
14775 }
14776 var className = "ace_fold-widget ace_" + c;
14777 if (c == "start" && row == foldStart && row < fold.end.row)
14778 className += " ace_closed";
14779 else
14780 className += " ace_open";
14781 if (cell.foldWidget.className != className)
14782 cell.foldWidget.className = className;
14783
14784 var height = config.lineHeight + "px";
14785 if (cell.foldWidget.style.height != height)
14786 cell.foldWidget.style.height = height;
14787 } else {
14788 if (cell.foldWidget) {
14789 cell.element.removeChild(cell.foldWidget);
14790 cell.foldWidget = null;
14791 }
14792 }
14793
14794 var text = lastLineNumber = gutterRenderer
14795 ? gutterRenderer.getText(session, row)
14796 : row + firstLineNumber;
14797 if (text !== cell.textNode.data)
14798 cell.textNode.data = text;
14799
14800 row++;
14801 }
14802
14803 this.element.style.height = config.minHeight + "px";
14804
14805 if (this.$fixedWidth || session.$useWrapMode)
14806 lastLineNumber = session.getLength() + firstLineNumber;
14807
14808 var gutterWidth = gutterRenderer
14809 ? gutterRenderer.getWidth(session, lastLineNumber, config)
14810 : lastLineNumber.toString().length * config.characterWidth;
14811
14812 var padding = this.$padding || this.$computePadding();
14813 gutterWidth += padding.left + padding.right;
14814 if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {
14815 this.gutterWidth = gutterWidth;
14816 this.element.style.width = Math.ceil(this.gutterWidth) + "px";
14817 this._emit("changeGutterWidth", gutterWidth);
14818 }
14819 };
14820
14821 this.$fixedWidth = false;
14822
14823 this.$showLineNumbers = true;
14824 this.$renderer = "";
14825 this.setShowLineNumbers = function(show) {
14826 this.$renderer = !show && {
14827 getWidth: function() {return "";},
14828 getText: function() {return "";}
14829 };
14830 };
14831
14832 this.getShowLineNumbers = function() {
14833 return this.$showLineNumbers;
14834 };
14835
14836 this.$showFoldWidgets = true;
14837 this.setShowFoldWidgets = function(show) {
14838 if (show)
14839 dom.addCssClass(this.element, "ace_folding-enabled");
14840 else
14841 dom.removeCssClass(this.element, "ace_folding-enabled");
14842
14843 this.$showFoldWidgets = show;
14844 this.$padding = null;
14845 };
14846
14847 this.getShowFoldWidgets = function() {
14848 return this.$showFoldWidgets;
14849 };
14850
14851 this.$computePadding = function() {
14852 if (!this.element.firstChild)
14853 return {left: 0, right: 0};
14854 var style = dom.computedStyle(this.element.firstChild);
14855 this.$padding = {};
14856 this.$padding.left = parseInt(style.paddingLeft) + 1 || 0;
14857 this.$padding.right = parseInt(style.paddingRight) || 0;
14858 return this.$padding;
14859 };
14860
14861 this.getRegion = function(point) {
14862 var padding = this.$padding || this.$computePadding();
14863 var rect = this.element.getBoundingClientRect();
14864 if (point.x < padding.left + rect.left)
14865 return "markers";
14866 if (this.$showFoldWidgets && point.x > rect.right - padding.right)
14867 return "foldWidgets";
14868 };
14869
14870}).call(Gutter.prototype);
14871
14872exports.Gutter = Gutter;
14873
14874});
14875
14876ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"], function(acequire, exports, module) {
14877
14878var Range = acequire("../range").Range;
14879var dom = acequire("../lib/dom");
14880
14881var Marker = function(parentEl) {
14882 this.element = dom.createElement("div");
14883 this.element.className = "ace_layer ace_marker-layer";
14884 parentEl.appendChild(this.element);
14885};
14886
14887(function() {
14888
14889 this.$padding = 0;
14890
14891 this.setPadding = function(padding) {
14892 this.$padding = padding;
14893 };
14894 this.setSession = function(session) {
14895 this.session = session;
14896 };
14897
14898 this.setMarkers = function(markers) {
14899 this.markers = markers;
14900 };
14901
14902 this.update = function(config) {
14903 if (!config) return;
14904
14905 this.config = config;
14906
14907
14908 var html = [];
14909 for (var key in this.markers) {
14910 var marker = this.markers[key];
14911
14912 if (!marker.range) {
14913 marker.update(html, this, this.session, config);
14914 continue;
14915 }
14916
14917 var range = marker.range.clipRows(config.firstRow, config.lastRow);
14918 if (range.isEmpty()) continue;
14919
14920 range = range.toScreenRange(this.session);
14921 if (marker.renderer) {
14922 var top = this.$getTop(range.start.row, config);
14923 var left = this.$padding + (this.session.$bidiHandler.isBidiRow(range.start.row)
14924 ? this.session.$bidiHandler.getPosLeft(range.start.column)
14925 : range.start.column * config.characterWidth);
14926 marker.renderer(html, range, left, top, config);
14927 } else if (marker.type == "fullLine") {
14928 this.drawFullLineMarker(html, range, marker.clazz, config);
14929 } else if (marker.type == "screenLine") {
14930 this.drawScreenLineMarker(html, range, marker.clazz, config);
14931 } else if (range.isMultiLine()) {
14932 if (marker.type == "text")
14933 this.drawTextMarker(html, range, marker.clazz, config);
14934 else
14935 this.drawMultiLineMarker(html, range, marker.clazz, config);
14936 } else {
14937 if (this.session.$bidiHandler.isBidiRow(range.start.row)) {
14938 this.drawBidiSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config);
14939 } else {
14940 this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config);
14941 }
14942 }
14943 }
14944 this.element.innerHTML = html.join("");
14945 };
14946
14947 this.$getTop = function(row, layerConfig) {
14948 return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
14949 };
14950
14951 function getBorderClass(tl, tr, br, bl) {
14952 return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0);
14953 }
14954 this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) {
14955 var session = this.session;
14956 var start = range.start.row;
14957 var end = range.end.row;
14958 var row = start;
14959 var prev = 0;
14960 var curr = 0;
14961 var next = session.getScreenLastRowColumn(row);
14962 var clazzModified = null;
14963 var lineRange = new Range(row, range.start.column, row, curr);
14964 for (; row <= end; row++) {
14965 lineRange.start.row = lineRange.end.row = row;
14966 lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row);
14967 lineRange.end.column = next;
14968 prev = curr;
14969 curr = next;
14970 next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column;
14971 clazzModified = clazz + (row == start ? " ace_start" : "") + " ace_br"
14972 + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end);
14973
14974 if (this.session.$bidiHandler.isBidiRow(row)) {
14975 this.drawBidiSingleLineMarker(stringBuilder, lineRange, clazzModified,
14976 layerConfig, row == end ? 0 : 1, extraStyle);
14977 } else {
14978 this.drawSingleLineMarker(stringBuilder, lineRange, clazzModified,
14979 layerConfig, row == end ? 0 : 1, extraStyle);
14980 }
14981 }
14982 };
14983 this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
14984 var padding = this.$padding;
14985 var height, top, left;
14986 extraStyle = extraStyle || "";
14987 if (this.session.$bidiHandler.isBidiRow(range.start.row)) {
14988 var range1 = range.clone();
14989 range1.end.row = range1.start.row;
14990 range1.end.column = this.session.getLine(range1.start.row).length;
14991 this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br1 ace_start", config, null, extraStyle);
14992 } else {
14993 height = config.lineHeight;
14994 top = this.$getTop(range.start.row, config);
14995 left = padding + range.start.column * config.characterWidth;
14996 stringBuilder.push(
14997 "<div class='", clazz, " ace_br1 ace_start' style='",
14998 "height:", height, "px;",
14999 "right:0;",
15000 "top:", top, "px;",
15001 "left:", left, "px;", extraStyle, "'></div>"
15002 );
15003 }
15004 if (this.session.$bidiHandler.isBidiRow(range.end.row)) {
15005 var range1 = range.clone();
15006 range1.start.row = range1.end.row;
15007 range1.start.column = 0;
15008 this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br12", config, null, extraStyle);
15009 } else {
15010 var width = range.end.column * config.characterWidth;
15011 height = config.lineHeight;
15012 top = this.$getTop(range.end.row, config);
15013 stringBuilder.push(
15014 "<div class='", clazz, " ace_br12' style='",
15015 "height:", height, "px;",
15016 "width:", width, "px;",
15017 "top:", top, "px;",
15018 "left:", padding, "px;", extraStyle, "'></div>"
15019 );
15020 }
15021 height = (range.end.row - range.start.row - 1) * config.lineHeight;
15022 if (height <= 0)
15023 return;
15024 top = this.$getTop(range.start.row + 1, config);
15025
15026 var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8);
15027
15028 stringBuilder.push(
15029 "<div class='", clazz, (radiusClass ? " ace_br" + radiusClass : ""), "' style='",
15030 "height:", height, "px;",
15031 "right:0;",
15032 "top:", top, "px;",
15033 "left:", padding, "px;", extraStyle, "'></div>"
15034 );
15035 };
15036 this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
15037 var height = config.lineHeight;
15038 var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;
15039
15040 var top = this.$getTop(range.start.row, config);
15041 var left = this.$padding + range.start.column * config.characterWidth;
15042
15043 stringBuilder.push(
15044 "<div class='", clazz, "' style='",
15045 "height:", height, "px;",
15046 "width:", width, "px;",
15047 "top:", top, "px;",
15048 "left:", left, "px;", extraStyle || "", "'></div>"
15049 );
15050 };
15051 this.drawBidiSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
15052 var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding;
15053 var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column);
15054
15055 selections.forEach(function(selection) {
15056 stringBuilder.push(
15057 "<div class='", clazz, "' style='",
15058 "height:", height, "px;",
15059 "width:", selection.width + (extraLength || 0), "px;",
15060 "top:", top, "px;",
15061 "left:", padding + selection.left, "px;", extraStyle || "", "'></div>"
15062 );
15063 });
15064 };
15065
15066 this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15067 var top = this.$getTop(range.start.row, config);
15068 var height = config.lineHeight;
15069 if (range.start.row != range.end.row)
15070 height += this.$getTop(range.end.row, config) - top;
15071
15072 stringBuilder.push(
15073 "<div class='", clazz, "' style='",
15074 "height:", height, "px;",
15075 "top:", top, "px;",
15076 "left:0;right:0;", extraStyle || "", "'></div>"
15077 );
15078 };
15079
15080 this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15081 var top = this.$getTop(range.start.row, config);
15082 var height = config.lineHeight;
15083
15084 stringBuilder.push(
15085 "<div class='", clazz, "' style='",
15086 "height:", height, "px;",
15087 "top:", top, "px;",
15088 "left:0;right:0;", extraStyle || "", "'></div>"
15089 );
15090 };
15091
15092}).call(Marker.prototype);
15093
15094exports.Marker = Marker;
15095
15096});
15097
15098ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(acequire, exports, module) {
15099
15100var oop = acequire("../lib/oop");
15101var dom = acequire("../lib/dom");
15102var lang = acequire("../lib/lang");
15103acequire("../lib/useragent");
15104var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
15105
15106var Text = function(parentEl) {
15107 this.element = dom.createElement("div");
15108 this.element.className = "ace_layer ace_text-layer";
15109 parentEl.appendChild(this.element);
15110 this.$updateEolChar = this.$updateEolChar.bind(this);
15111};
15112
15113(function() {
15114
15115 oop.implement(this, EventEmitter);
15116
15117 this.EOF_CHAR = "\xB6";
15118 this.EOL_CHAR_LF = "\xAC";
15119 this.EOL_CHAR_CRLF = "\xa4";
15120 this.EOL_CHAR = this.EOL_CHAR_LF;
15121 this.TAB_CHAR = "\u2014"; //"\u21E5";
15122 this.SPACE_CHAR = "\xB7";
15123 this.$padding = 0;
15124
15125 this.$updateEolChar = function() {
15126 var EOL_CHAR = this.session.doc.getNewLineCharacter() == "\n"
15127 ? this.EOL_CHAR_LF
15128 : this.EOL_CHAR_CRLF;
15129 if (this.EOL_CHAR != EOL_CHAR) {
15130 this.EOL_CHAR = EOL_CHAR;
15131 return true;
15132 }
15133 };
15134
15135 this.setPadding = function(padding) {
15136 this.$padding = padding;
15137 this.element.style.padding = "0 " + padding + "px";
15138 };
15139
15140 this.getLineHeight = function() {
15141 return this.$fontMetrics.$characterSize.height || 0;
15142 };
15143
15144 this.getCharacterWidth = function() {
15145 return this.$fontMetrics.$characterSize.width || 0;
15146 };
15147
15148 this.$setFontMetrics = function(measure) {
15149 this.$fontMetrics = measure;
15150 this.$fontMetrics.on("changeCharacterSize", function(e) {
15151 this._signal("changeCharacterSize", e);
15152 }.bind(this));
15153 this.$pollSizeChanges();
15154 };
15155
15156 this.checkForSizeChanges = function() {
15157 this.$fontMetrics.checkForSizeChanges();
15158 };
15159 this.$pollSizeChanges = function() {
15160 return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();
15161 };
15162 this.setSession = function(session) {
15163 this.session = session;
15164 if (session)
15165 this.$computeTabString();
15166 };
15167
15168 this.showInvisibles = false;
15169 this.setShowInvisibles = function(showInvisibles) {
15170 if (this.showInvisibles == showInvisibles)
15171 return false;
15172
15173 this.showInvisibles = showInvisibles;
15174 this.$computeTabString();
15175 return true;
15176 };
15177
15178 this.displayIndentGuides = true;
15179 this.setDisplayIndentGuides = function(display) {
15180 if (this.displayIndentGuides == display)
15181 return false;
15182
15183 this.displayIndentGuides = display;
15184 this.$computeTabString();
15185 return true;
15186 };
15187
15188 this.$tabStrings = [];
15189 this.onChangeTabSize =
15190 this.$computeTabString = function() {
15191 var tabSize = this.session.getTabSize();
15192 this.tabSize = tabSize;
15193 var tabStr = this.$tabStrings = [0];
15194 for (var i = 1; i < tabSize + 1; i++) {
15195 if (this.showInvisibles) {
15196 tabStr.push("<span class='ace_invisible ace_invisible_tab'>"
15197 + lang.stringRepeat(this.TAB_CHAR, i)
15198 + "</span>");
15199 } else {
15200 tabStr.push(lang.stringRepeat(" ", i));
15201 }
15202 }
15203 if (this.displayIndentGuides) {
15204 this.$indentGuideRe = /\s\S| \t|\t |\s$/;
15205 var className = "ace_indent-guide";
15206 var spaceClass = "";
15207 var tabClass = "";
15208 if (this.showInvisibles) {
15209 className += " ace_invisible";
15210 spaceClass = " ace_invisible_space";
15211 tabClass = " ace_invisible_tab";
15212 var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);
15213 var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize);
15214 } else {
15215 var spaceContent = lang.stringRepeat(" ", this.tabSize);
15216 var tabContent = spaceContent;
15217 }
15218
15219 this.$tabStrings[" "] = "<span class='" + className + spaceClass + "'>" + spaceContent + "</span>";
15220 this.$tabStrings["\t"] = "<span class='" + className + tabClass + "'>" + tabContent + "</span>";
15221 }
15222 };
15223
15224 this.updateLines = function(config, firstRow, lastRow) {
15225 if (this.config.lastRow != config.lastRow ||
15226 this.config.firstRow != config.firstRow) {
15227 this.scrollLines(config);
15228 }
15229 this.config = config;
15230
15231 var first = Math.max(firstRow, config.firstRow);
15232 var last = Math.min(lastRow, config.lastRow);
15233
15234 var lineElements = this.element.childNodes;
15235 var lineElementsIdx = 0;
15236
15237 for (var row = config.firstRow; row < first; row++) {
15238 var foldLine = this.session.getFoldLine(row);
15239 if (foldLine) {
15240 if (foldLine.containsRow(first)) {
15241 first = foldLine.start.row;
15242 break;
15243 } else {
15244 row = foldLine.end.row;
15245 }
15246 }
15247 lineElementsIdx ++;
15248 }
15249
15250 var row = first;
15251 var foldLine = this.session.getNextFoldLine(row);
15252 var foldStart = foldLine ? foldLine.start.row : Infinity;
15253
15254 while (true) {
15255 if (row > foldStart) {
15256 row = foldLine.end.row+1;
15257 foldLine = this.session.getNextFoldLine(row, foldLine);
15258 foldStart = foldLine ? foldLine.start.row :Infinity;
15259 }
15260 if (row > last)
15261 break;
15262
15263 var lineElement = lineElements[lineElementsIdx++];
15264 if (lineElement) {
15265 var html = [];
15266 this.$renderLine(
15267 html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
15268 );
15269 lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
15270 lineElement.innerHTML = html.join("");
15271 }
15272 row++;
15273 }
15274 };
15275
15276 this.scrollLines = function(config) {
15277 var oldConfig = this.config;
15278 this.config = config;
15279
15280 if (!oldConfig || oldConfig.lastRow < config.firstRow)
15281 return this.update(config);
15282
15283 if (config.lastRow < oldConfig.firstRow)
15284 return this.update(config);
15285
15286 var el = this.element;
15287 if (oldConfig.firstRow < config.firstRow)
15288 for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
15289 el.removeChild(el.firstChild);
15290
15291 if (oldConfig.lastRow > config.lastRow)
15292 for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
15293 el.removeChild(el.lastChild);
15294
15295 if (config.firstRow < oldConfig.firstRow) {
15296 var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
15297 if (el.firstChild)
15298 el.insertBefore(fragment, el.firstChild);
15299 else
15300 el.appendChild(fragment);
15301 }
15302
15303 if (config.lastRow > oldConfig.lastRow) {
15304 var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);
15305 el.appendChild(fragment);
15306 }
15307 };
15308
15309 this.$renderLinesFragment = function(config, firstRow, lastRow) {
15310 var fragment = this.element.ownerDocument.createDocumentFragment();
15311 var row = firstRow;
15312 var foldLine = this.session.getNextFoldLine(row);
15313 var foldStart = foldLine ? foldLine.start.row : Infinity;
15314
15315 while (true) {
15316 if (row > foldStart) {
15317 row = foldLine.end.row+1;
15318 foldLine = this.session.getNextFoldLine(row, foldLine);
15319 foldStart = foldLine ? foldLine.start.row : Infinity;
15320 }
15321 if (row > lastRow)
15322 break;
15323
15324 var container = dom.createElement("div");
15325
15326 var html = [];
15327 this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
15328 container.innerHTML = html.join("");
15329 if (this.$useLineGroups()) {
15330 container.className = 'ace_line_group';
15331 fragment.appendChild(container);
15332 container.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
15333
15334 } else {
15335 while(container.firstChild)
15336 fragment.appendChild(container.firstChild);
15337 }
15338
15339 row++;
15340 }
15341 return fragment;
15342 };
15343
15344 this.update = function(config) {
15345 this.config = config;
15346
15347 var html = [];
15348 var firstRow = config.firstRow, lastRow = config.lastRow;
15349
15350 var row = firstRow;
15351 var foldLine = this.session.getNextFoldLine(row);
15352 var foldStart = foldLine ? foldLine.start.row : Infinity;
15353
15354 while (true) {
15355 if (row > foldStart) {
15356 row = foldLine.end.row+1;
15357 foldLine = this.session.getNextFoldLine(row, foldLine);
15358 foldStart = foldLine ? foldLine.start.row :Infinity;
15359 }
15360 if (row > lastRow)
15361 break;
15362
15363 if (this.$useLineGroups())
15364 html.push("<div class='ace_line_group' style='height:", config.lineHeight*this.session.getRowLength(row), "px'>");
15365
15366 this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
15367
15368 if (this.$useLineGroups())
15369 html.push("</div>"); // end the line group
15370
15371 row++;
15372 }
15373 this.element.innerHTML = html.join("");
15374 };
15375
15376 this.$textToken = {
15377 "text": true,
15378 "rparen": true,
15379 "lparen": true
15380 };
15381
15382 this.$renderToken = function(stringBuilder, screenColumn, token, value) {
15383 var self = this;
15384 var replaceReg = /\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
15385 var replaceFunc = function(c, a, b, tabIdx, idx4) {
15386 if (a) {
15387 return self.showInvisibles
15388 ? "<span class='ace_invisible ace_invisible_space'>" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "</span>"
15389 : c;
15390 } else if (c == "&") {
15391 return "&#38;";
15392 } else if (c == "<") {
15393 return "&#60;";
15394 } else if (c == ">") {
15395 return "&#62;";
15396 } else if (c == "\t") {
15397 var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
15398 screenColumn += tabSize - 1;
15399 return self.$tabStrings[tabSize];
15400 } else if (c == "\u3000") {
15401 var classToUse = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk";
15402 var space = self.showInvisibles ? self.SPACE_CHAR : "";
15403 screenColumn += 1;
15404 return "<span class='" + classToUse + "' style='width:" +
15405 (self.config.characterWidth * 2) +
15406 "px'>" + space + "</span>";
15407 } else if (b) {
15408 return "<span class='ace_invisible ace_invisible_space ace_invalid'>" + self.SPACE_CHAR + "</span>";
15409 } else {
15410 screenColumn += 1;
15411 return "<span class='ace_cjk' style='width:" +
15412 (self.config.characterWidth * 2) +
15413 "px'>" + c + "</span>";
15414 }
15415 };
15416
15417 var output = value.replace(replaceReg, replaceFunc);
15418
15419 if (!this.$textToken[token.type]) {
15420 var classes = "ace_" + token.type.replace(/\./g, " ace_");
15421 var style = "";
15422 if (token.type == "fold")
15423 style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' ";
15424 stringBuilder.push("<span class='", classes, "'", style, ">", output, "</span>");
15425 }
15426 else {
15427 stringBuilder.push(output);
15428 }
15429 return screenColumn + value.length;
15430 };
15431
15432 this.renderIndentGuide = function(stringBuilder, value, max) {
15433 var cols = value.search(this.$indentGuideRe);
15434 if (cols <= 0 || cols >= max)
15435 return value;
15436 if (value[0] == " ") {
15437 cols -= cols % this.tabSize;
15438 stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize));
15439 return value.substr(cols);
15440 } else if (value[0] == "\t") {
15441 stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols));
15442 return value.substr(cols);
15443 }
15444 return value;
15445 };
15446
15447 this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
15448 var chars = 0;
15449 var split = 0;
15450 var splitChars = splits[0];
15451 var screenColumn = 0;
15452
15453 for (var i = 0; i < tokens.length; i++) {
15454 var token = tokens[i];
15455 var value = token.value;
15456 if (i == 0 && this.displayIndentGuides) {
15457 chars = value.length;
15458 value = this.renderIndentGuide(stringBuilder, value, splitChars);
15459 if (!value)
15460 continue;
15461 chars -= value.length;
15462 }
15463
15464 if (chars + value.length < splitChars) {
15465 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15466 chars += value.length;
15467 } else {
15468 while (chars + value.length >= splitChars) {
15469 screenColumn = this.$renderToken(
15470 stringBuilder, screenColumn,
15471 token, value.substring(0, splitChars - chars)
15472 );
15473 value = value.substring(splitChars - chars);
15474 chars = splitChars;
15475
15476 if (!onlyContents) {
15477 stringBuilder.push("</div>",
15478 "<div class='ace_line' style='height:",
15479 this.config.lineHeight, "px'>"
15480 );
15481 }
15482
15483 stringBuilder.push(lang.stringRepeat("\xa0", splits.indent));
15484
15485 split ++;
15486 screenColumn = 0;
15487 splitChars = splits[split] || Number.MAX_VALUE;
15488 }
15489 if (value.length != 0) {
15490 chars += value.length;
15491 screenColumn = this.$renderToken(
15492 stringBuilder, screenColumn, token, value
15493 );
15494 }
15495 }
15496 }
15497 };
15498
15499 this.$renderSimpleLine = function(stringBuilder, tokens) {
15500 var screenColumn = 0;
15501 var token = tokens[0];
15502 var value = token.value;
15503 if (this.displayIndentGuides)
15504 value = this.renderIndentGuide(stringBuilder, value);
15505 if (value)
15506 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15507 for (var i = 1; i < tokens.length; i++) {
15508 token = tokens[i];
15509 value = token.value;
15510 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15511 }
15512 };
15513 this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
15514 if (!foldLine && foldLine != false)
15515 foldLine = this.session.getFoldLine(row);
15516
15517 if (foldLine)
15518 var tokens = this.$getFoldLineTokens(row, foldLine);
15519 else
15520 var tokens = this.session.getTokens(row);
15521
15522
15523 if (!onlyContents) {
15524 stringBuilder.push(
15525 "<div class='ace_line' style='height:",
15526 this.config.lineHeight * (
15527 this.$useLineGroups() ? 1 :this.session.getRowLength(row)
15528 ), "px'>"
15529 );
15530 }
15531
15532 if (tokens.length) {
15533 var splits = this.session.getRowSplitData(row);
15534 if (splits && splits.length)
15535 this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
15536 else
15537 this.$renderSimpleLine(stringBuilder, tokens);
15538 }
15539
15540 if (this.showInvisibles) {
15541 if (foldLine)
15542 row = foldLine.end.row;
15543
15544 stringBuilder.push(
15545 "<span class='ace_invisible ace_invisible_eol'>",
15546 row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
15547 "</span>"
15548 );
15549 }
15550 if (!onlyContents)
15551 stringBuilder.push("</div>");
15552 };
15553
15554 this.$getFoldLineTokens = function(row, foldLine) {
15555 var session = this.session;
15556 var renderTokens = [];
15557
15558 function addTokens(tokens, from, to) {
15559 var idx = 0, col = 0;
15560 while ((col + tokens[idx].value.length) < from) {
15561 col += tokens[idx].value.length;
15562 idx++;
15563
15564 if (idx == tokens.length)
15565 return;
15566 }
15567 if (col != from) {
15568 var value = tokens[idx].value.substring(from - col);
15569 if (value.length > (to - from))
15570 value = value.substring(0, to - from);
15571
15572 renderTokens.push({
15573 type: tokens[idx].type,
15574 value: value
15575 });
15576
15577 col = from + value.length;
15578 idx += 1;
15579 }
15580
15581 while (col < to && idx < tokens.length) {
15582 var value = tokens[idx].value;
15583 if (value.length + col > to) {
15584 renderTokens.push({
15585 type: tokens[idx].type,
15586 value: value.substring(0, to - col)
15587 });
15588 } else
15589 renderTokens.push(tokens[idx]);
15590 col += value.length;
15591 idx += 1;
15592 }
15593 }
15594
15595 var tokens = session.getTokens(row);
15596 foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
15597 if (placeholder != null) {
15598 renderTokens.push({
15599 type: "fold",
15600 value: placeholder
15601 });
15602 } else {
15603 if (isNewRow)
15604 tokens = session.getTokens(row);
15605
15606 if (tokens.length)
15607 addTokens(tokens, lastColumn, column);
15608 }
15609 }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
15610
15611 return renderTokens;
15612 };
15613
15614 this.$useLineGroups = function() {
15615 return this.session.getUseWrapMode();
15616 };
15617
15618 this.destroy = function() {
15619 clearInterval(this.$pollSizeChangesTimer);
15620 if (this.$measureNode)
15621 this.$measureNode.parentNode.removeChild(this.$measureNode);
15622 delete this.$measureNode;
15623 };
15624
15625}).call(Text.prototype);
15626
15627exports.Text = Text;
15628
15629});
15630
15631ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) {
15632
15633var dom = acequire("../lib/dom");
15634var isIE8;
15635
15636var Cursor = function(parentEl) {
15637 this.element = dom.createElement("div");
15638 this.element.className = "ace_layer ace_cursor-layer";
15639 parentEl.appendChild(this.element);
15640
15641 if (isIE8 === undefined)
15642 isIE8 = !("opacity" in this.element.style);
15643
15644 this.isVisible = false;
15645 this.isBlinking = true;
15646 this.blinkInterval = 1000;
15647 this.smoothBlinking = false;
15648
15649 this.cursors = [];
15650 this.cursor = this.addCursor();
15651 dom.addCssClass(this.element, "ace_hidden-cursors");
15652 this.$updateCursors = (isIE8
15653 ? this.$updateVisibility
15654 : this.$updateOpacity).bind(this);
15655};
15656
15657(function() {
15658
15659 this.$updateVisibility = function(val) {
15660 var cursors = this.cursors;
15661 for (var i = cursors.length; i--; )
15662 cursors[i].style.visibility = val ? "" : "hidden";
15663 };
15664 this.$updateOpacity = function(val) {
15665 var cursors = this.cursors;
15666 for (var i = cursors.length; i--; )
15667 cursors[i].style.opacity = val ? "" : "0";
15668 };
15669
15670
15671 this.$padding = 0;
15672 this.setPadding = function(padding) {
15673 this.$padding = padding;
15674 };
15675
15676 this.setSession = function(session) {
15677 this.session = session;
15678 };
15679
15680 this.setBlinking = function(blinking) {
15681 if (blinking != this.isBlinking){
15682 this.isBlinking = blinking;
15683 this.restartTimer();
15684 }
15685 };
15686
15687 this.setBlinkInterval = function(blinkInterval) {
15688 if (blinkInterval != this.blinkInterval){
15689 this.blinkInterval = blinkInterval;
15690 this.restartTimer();
15691 }
15692 };
15693
15694 this.setSmoothBlinking = function(smoothBlinking) {
15695 if (smoothBlinking != this.smoothBlinking && !isIE8) {
15696 this.smoothBlinking = smoothBlinking;
15697 dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking);
15698 this.$updateCursors(true);
15699 this.$updateCursors = (this.$updateOpacity).bind(this);
15700 this.restartTimer();
15701 }
15702 };
15703
15704 this.addCursor = function() {
15705 var el = dom.createElement("div");
15706 el.className = "ace_cursor";
15707 this.element.appendChild(el);
15708 this.cursors.push(el);
15709 return el;
15710 };
15711
15712 this.removeCursor = function() {
15713 if (this.cursors.length > 1) {
15714 var el = this.cursors.pop();
15715 el.parentNode.removeChild(el);
15716 return el;
15717 }
15718 };
15719
15720 this.hideCursor = function() {
15721 this.isVisible = false;
15722 dom.addCssClass(this.element, "ace_hidden-cursors");
15723 this.restartTimer();
15724 };
15725
15726 this.showCursor = function() {
15727 this.isVisible = true;
15728 dom.removeCssClass(this.element, "ace_hidden-cursors");
15729 this.restartTimer();
15730 };
15731
15732 this.restartTimer = function() {
15733 var update = this.$updateCursors;
15734 clearInterval(this.intervalId);
15735 clearTimeout(this.timeoutId);
15736 if (this.smoothBlinking) {
15737 dom.removeCssClass(this.element, "ace_smooth-blinking");
15738 }
15739
15740 update(true);
15741
15742 if (!this.isBlinking || !this.blinkInterval || !this.isVisible)
15743 return;
15744
15745 if (this.smoothBlinking) {
15746 setTimeout(function(){
15747 dom.addCssClass(this.element, "ace_smooth-blinking");
15748 }.bind(this));
15749 }
15750
15751 var blink = function(){
15752 this.timeoutId = setTimeout(function() {
15753 update(false);
15754 }, 0.6 * this.blinkInterval);
15755 }.bind(this);
15756
15757 this.intervalId = setInterval(function() {
15758 update(true);
15759 blink();
15760 }, this.blinkInterval);
15761
15762 blink();
15763 };
15764
15765 this.getPixelPosition = function(position, onScreen) {
15766 if (!this.config || !this.session)
15767 return {left : 0, top : 0};
15768
15769 if (!position)
15770 position = this.session.selection.getCursor();
15771 var pos = this.session.documentToScreenPosition(position);
15772 var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row)
15773 ? this.session.$bidiHandler.getPosLeft(pos.column)
15774 : pos.column * this.config.characterWidth);
15775
15776 var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
15777 this.config.lineHeight;
15778
15779 return {left : cursorLeft, top : cursorTop};
15780 };
15781
15782 this.update = function(config) {
15783 this.config = config;
15784
15785 var selections = this.session.$selectionMarkers;
15786 var i = 0, cursorIndex = 0;
15787
15788 if (selections === undefined || selections.length === 0){
15789 selections = [{cursor: null}];
15790 }
15791
15792 for (var i = 0, n = selections.length; i < n; i++) {
15793 var pixelPos = this.getPixelPosition(selections[i].cursor, true);
15794 if ((pixelPos.top > config.height + config.offset ||
15795 pixelPos.top < 0) && i > 1) {
15796 continue;
15797 }
15798
15799 var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
15800
15801 if (!this.drawCursor) {
15802 style.left = pixelPos.left + "px";
15803 style.top = pixelPos.top + "px";
15804 style.width = config.characterWidth + "px";
15805 style.height = config.lineHeight + "px";
15806 } else {
15807 this.drawCursor(style, pixelPos, config, selections[i], this.session);
15808 }
15809 }
15810 while (this.cursors.length > cursorIndex)
15811 this.removeCursor();
15812
15813 var overwrite = this.session.getOverwrite();
15814 this.$setOverwrite(overwrite);
15815 this.$pixelPos = pixelPos;
15816 this.restartTimer();
15817 };
15818
15819 this.drawCursor = null;
15820
15821 this.$setOverwrite = function(overwrite) {
15822 if (overwrite != this.overwrite) {
15823 this.overwrite = overwrite;
15824 if (overwrite)
15825 dom.addCssClass(this.element, "ace_overwrite-cursors");
15826 else
15827 dom.removeCssClass(this.element, "ace_overwrite-cursors");
15828 }
15829 };
15830
15831 this.destroy = function() {
15832 clearInterval(this.intervalId);
15833 clearTimeout(this.timeoutId);
15834 };
15835
15836}).call(Cursor.prototype);
15837
15838exports.Cursor = Cursor;
15839
15840});
15841
15842ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"], function(acequire, exports, module) {
15843
15844var oop = acequire("./lib/oop");
15845var dom = acequire("./lib/dom");
15846var event = acequire("./lib/event");
15847var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
15848var MAX_SCROLL_H = 0x8000;
15849var ScrollBar = function(parent) {
15850 this.element = dom.createElement("div");
15851 this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix;
15852
15853 this.inner = dom.createElement("div");
15854 this.inner.className = "ace_scrollbar-inner";
15855 this.element.appendChild(this.inner);
15856
15857 parent.appendChild(this.element);
15858
15859 this.setVisible(false);
15860 this.skipEvent = false;
15861
15862 event.addListener(this.element, "scroll", this.onScroll.bind(this));
15863 event.addListener(this.element, "mousedown", event.preventDefault);
15864};
15865
15866(function() {
15867 oop.implement(this, EventEmitter);
15868
15869 this.setVisible = function(isVisible) {
15870 this.element.style.display = isVisible ? "" : "none";
15871 this.isVisible = isVisible;
15872 this.coeff = 1;
15873 };
15874}).call(ScrollBar.prototype);
15875var VScrollBar = function(parent, renderer) {
15876 ScrollBar.call(this, parent);
15877 this.scrollTop = 0;
15878 this.scrollHeight = 0;
15879 renderer.$scrollbarWidth =
15880 this.width = dom.scrollbarWidth(parent.ownerDocument);
15881 this.inner.style.width =
15882 this.element.style.width = (this.width || 15) + 5 + "px";
15883 this.$minWidth = 0;
15884};
15885
15886oop.inherits(VScrollBar, ScrollBar);
15887
15888(function() {
15889
15890 this.classSuffix = '-v';
15891 this.onScroll = function() {
15892 if (!this.skipEvent) {
15893 this.scrollTop = this.element.scrollTop;
15894 if (this.coeff != 1) {
15895 var h = this.element.clientHeight / this.scrollHeight;
15896 this.scrollTop = this.scrollTop * (1 - h) / (this.coeff - h);
15897 }
15898 this._emit("scroll", {data: this.scrollTop});
15899 }
15900 this.skipEvent = false;
15901 };
15902 this.getWidth = function() {
15903 return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0);
15904 };
15905 this.setHeight = function(height) {
15906 this.element.style.height = height + "px";
15907 };
15908 this.setInnerHeight =
15909 this.setScrollHeight = function(height) {
15910 this.scrollHeight = height;
15911 if (height > MAX_SCROLL_H) {
15912 this.coeff = MAX_SCROLL_H / height;
15913 height = MAX_SCROLL_H;
15914 } else if (this.coeff != 1) {
15915 this.coeff = 1;
15916 }
15917 this.inner.style.height = height + "px";
15918 };
15919 this.setScrollTop = function(scrollTop) {
15920 if (this.scrollTop != scrollTop) {
15921 this.skipEvent = true;
15922 this.scrollTop = scrollTop;
15923 this.element.scrollTop = scrollTop * this.coeff;
15924 }
15925 };
15926
15927}).call(VScrollBar.prototype);
15928var HScrollBar = function(parent, renderer) {
15929 ScrollBar.call(this, parent);
15930 this.scrollLeft = 0;
15931 this.height = renderer.$scrollbarWidth;
15932 this.inner.style.height =
15933 this.element.style.height = (this.height || 15) + 5 + "px";
15934};
15935
15936oop.inherits(HScrollBar, ScrollBar);
15937
15938(function() {
15939
15940 this.classSuffix = '-h';
15941 this.onScroll = function() {
15942 if (!this.skipEvent) {
15943 this.scrollLeft = this.element.scrollLeft;
15944 this._emit("scroll", {data: this.scrollLeft});
15945 }
15946 this.skipEvent = false;
15947 };
15948 this.getHeight = function() {
15949 return this.isVisible ? this.height : 0;
15950 };
15951 this.setWidth = function(width) {
15952 this.element.style.width = width + "px";
15953 };
15954 this.setInnerWidth = function(width) {
15955 this.inner.style.width = width + "px";
15956 };
15957 this.setScrollWidth = function(width) {
15958 this.inner.style.width = width + "px";
15959 };
15960 this.setScrollLeft = function(scrollLeft) {
15961 if (this.scrollLeft != scrollLeft) {
15962 this.skipEvent = true;
15963 this.scrollLeft = this.element.scrollLeft = scrollLeft;
15964 }
15965 };
15966
15967}).call(HScrollBar.prototype);
15968
15969
15970exports.ScrollBar = VScrollBar; // backward compatibility
15971exports.ScrollBarV = VScrollBar; // backward compatibility
15972exports.ScrollBarH = HScrollBar; // backward compatibility
15973
15974exports.VScrollBar = VScrollBar;
15975exports.HScrollBar = HScrollBar;
15976});
15977
15978ace.define("ace/renderloop",["require","exports","module","ace/lib/event"], function(acequire, exports, module) {
15979
15980var event = acequire("./lib/event");
15981
15982
15983var RenderLoop = function(onRender, win) {
15984 this.onRender = onRender;
15985 this.pending = false;
15986 this.changes = 0;
15987 this.window = win || window;
15988};
15989
15990(function() {
15991
15992
15993 this.schedule = function(change) {
15994 this.changes = this.changes | change;
15995 if (!this.pending && this.changes) {
15996 this.pending = true;
15997 var _self = this;
15998 event.nextFrame(function() {
15999 _self.pending = false;
16000 var changes;
16001 while (changes = _self.changes) {
16002 _self.changes = 0;
16003 _self.onRender(changes);
16004 }
16005 }, this.window);
16006 }
16007 };
16008
16009}).call(RenderLoop.prototype);
16010
16011exports.RenderLoop = RenderLoop;
16012});
16013
16014ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(acequire, exports, module) {
16015
16016var oop = acequire("../lib/oop");
16017var dom = acequire("../lib/dom");
16018var lang = acequire("../lib/lang");
16019var useragent = acequire("../lib/useragent");
16020var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
16021
16022var CHAR_COUNT = 0;
16023
16024var FontMetrics = exports.FontMetrics = function(parentEl) {
16025 this.el = dom.createElement("div");
16026 this.$setMeasureNodeStyles(this.el.style, true);
16027
16028 this.$main = dom.createElement("div");
16029 this.$setMeasureNodeStyles(this.$main.style);
16030
16031 this.$measureNode = dom.createElement("div");
16032 this.$setMeasureNodeStyles(this.$measureNode.style);
16033
16034
16035 this.el.appendChild(this.$main);
16036 this.el.appendChild(this.$measureNode);
16037 parentEl.appendChild(this.el);
16038
16039 if (!CHAR_COUNT)
16040 this.$testFractionalRect();
16041 this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT);
16042
16043 this.$characterSize = {width: 0, height: 0};
16044 this.checkForSizeChanges();
16045};
16046
16047(function() {
16048
16049 oop.implement(this, EventEmitter);
16050
16051 this.$characterSize = {width: 0, height: 0};
16052
16053 this.$testFractionalRect = function() {
16054 var el = dom.createElement("div");
16055 this.$setMeasureNodeStyles(el.style);
16056 el.style.width = "0.2px";
16057 document.documentElement.appendChild(el);
16058 var w = el.getBoundingClientRect().width;
16059 if (w > 0 && w < 1)
16060 CHAR_COUNT = 50;
16061 else
16062 CHAR_COUNT = 100;
16063 el.parentNode.removeChild(el);
16064 };
16065
16066 this.$setMeasureNodeStyles = function(style, isRoot) {
16067 style.width = style.height = "auto";
16068 style.left = style.top = "0px";
16069 style.visibility = "hidden";
16070 style.position = "absolute";
16071 style.whiteSpace = "pre";
16072
16073 if (useragent.isIE < 8) {
16074 style["font-family"] = "inherit";
16075 } else {
16076 style.font = "inherit";
16077 }
16078 style.overflow = isRoot ? "hidden" : "visible";
16079 };
16080
16081 this.checkForSizeChanges = function() {
16082 var size = this.$measureSizes();
16083 if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
16084 this.$measureNode.style.fontWeight = "bold";
16085 var boldSize = this.$measureSizes();
16086 this.$measureNode.style.fontWeight = "";
16087 this.$characterSize = size;
16088 this.charSizes = Object.create(null);
16089 this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
16090 this._emit("changeCharacterSize", {data: size});
16091 }
16092 };
16093
16094 this.$pollSizeChanges = function() {
16095 if (this.$pollSizeChangesTimer)
16096 return this.$pollSizeChangesTimer;
16097 var self = this;
16098 return this.$pollSizeChangesTimer = setInterval(function() {
16099 self.checkForSizeChanges();
16100 }, 500);
16101 };
16102
16103 this.setPolling = function(val) {
16104 if (val) {
16105 this.$pollSizeChanges();
16106 } else if (this.$pollSizeChangesTimer) {
16107 clearInterval(this.$pollSizeChangesTimer);
16108 this.$pollSizeChangesTimer = 0;
16109 }
16110 };
16111
16112 this.$measureSizes = function() {
16113 if (CHAR_COUNT === 50) {
16114 var rect = null;
16115 try {
16116 rect = this.$measureNode.getBoundingClientRect();
16117 } catch(e) {
16118 rect = {width: 0, height:0 };
16119 }
16120 var size = {
16121 height: rect.height,
16122 width: rect.width / CHAR_COUNT
16123 };
16124 } else {
16125 var size = {
16126 height: this.$measureNode.clientHeight,
16127 width: this.$measureNode.clientWidth / CHAR_COUNT
16128 };
16129 }
16130 if (size.width === 0 || size.height === 0)
16131 return null;
16132 return size;
16133 };
16134
16135 this.$measureCharWidth = function(ch) {
16136 this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT);
16137 var rect = this.$main.getBoundingClientRect();
16138 return rect.width / CHAR_COUNT;
16139 };
16140
16141 this.getCharacterWidth = function(ch) {
16142 var w = this.charSizes[ch];
16143 if (w === undefined) {
16144 w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width;
16145 }
16146 return w;
16147 };
16148
16149 this.destroy = function() {
16150 clearInterval(this.$pollSizeChangesTimer);
16151 if (this.el && this.el.parentNode)
16152 this.el.parentNode.removeChild(this.el);
16153 };
16154
16155}).call(FontMetrics.prototype);
16156
16157});
16158
16159ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"], function(acequire, exports, module) {
16160
16161var oop = acequire("./lib/oop");
16162var dom = acequire("./lib/dom");
16163var config = acequire("./config");
16164var useragent = acequire("./lib/useragent");
16165var GutterLayer = acequire("./layer/gutter").Gutter;
16166var MarkerLayer = acequire("./layer/marker").Marker;
16167var TextLayer = acequire("./layer/text").Text;
16168var CursorLayer = acequire("./layer/cursor").Cursor;
16169var HScrollBar = acequire("./scrollbar").HScrollBar;
16170var VScrollBar = acequire("./scrollbar").VScrollBar;
16171var RenderLoop = acequire("./renderloop").RenderLoop;
16172var FontMetrics = acequire("./layer/font_metrics").FontMetrics;
16173var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
16174var editorCss = ".ace_editor {\
16175position: relative;\
16176overflow: hidden;\
16177font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
16178direction: ltr;\
16179text-align: left;\
16180-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\
16181}\
16182.ace_scroller {\
16183position: absolute;\
16184overflow: hidden;\
16185top: 0;\
16186bottom: 0;\
16187background-color: inherit;\
16188-ms-user-select: none;\
16189-moz-user-select: none;\
16190-webkit-user-select: none;\
16191user-select: none;\
16192cursor: text;\
16193}\
16194.ace_content {\
16195position: absolute;\
16196-moz-box-sizing: border-box;\
16197-webkit-box-sizing: border-box;\
16198box-sizing: border-box;\
16199min-width: 100%;\
16200}\
16201.ace_dragging .ace_scroller:before{\
16202position: absolute;\
16203top: 0;\
16204left: 0;\
16205right: 0;\
16206bottom: 0;\
16207content: '';\
16208background: rgba(250, 250, 250, 0.01);\
16209z-index: 1000;\
16210}\
16211.ace_dragging.ace_dark .ace_scroller:before{\
16212background: rgba(0, 0, 0, 0.01);\
16213}\
16214.ace_selecting, .ace_selecting * {\
16215cursor: text !important;\
16216}\
16217.ace_gutter {\
16218position: absolute;\
16219overflow : hidden;\
16220width: auto;\
16221top: 0;\
16222bottom: 0;\
16223left: 0;\
16224cursor: default;\
16225z-index: 4;\
16226-ms-user-select: none;\
16227-moz-user-select: none;\
16228-webkit-user-select: none;\
16229user-select: none;\
16230}\
16231.ace_gutter-active-line {\
16232position: absolute;\
16233left: 0;\
16234right: 0;\
16235}\
16236.ace_scroller.ace_scroll-left {\
16237box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\
16238}\
16239.ace_gutter-cell {\
16240padding-left: 19px;\
16241padding-right: 6px;\
16242background-repeat: no-repeat;\
16243}\
16244.ace_gutter-cell.ace_error {\
16245background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");\
16246background-repeat: no-repeat;\
16247background-position: 2px center;\
16248}\
16249.ace_gutter-cell.ace_warning {\
16250background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");\
16251background-position: 2px center;\
16252}\
16253.ace_gutter-cell.ace_info {\
16254background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\
16255background-position: 2px center;\
16256}\
16257.ace_dark .ace_gutter-cell.ace_info {\
16258background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\
16259}\
16260.ace_scrollbar {\
16261position: absolute;\
16262right: 0;\
16263bottom: 0;\
16264z-index: 6;\
16265}\
16266.ace_scrollbar-inner {\
16267position: absolute;\
16268cursor: text;\
16269left: 0;\
16270top: 0;\
16271}\
16272.ace_scrollbar-v{\
16273overflow-x: hidden;\
16274overflow-y: scroll;\
16275top: 0;\
16276}\
16277.ace_scrollbar-h {\
16278overflow-x: scroll;\
16279overflow-y: hidden;\
16280left: 0;\
16281}\
16282.ace_print-margin {\
16283position: absolute;\
16284height: 100%;\
16285}\
16286.ace_text-input {\
16287position: absolute;\
16288z-index: 0;\
16289width: 0.5em;\
16290height: 1em;\
16291opacity: 0;\
16292background: transparent;\
16293-moz-appearance: none;\
16294appearance: none;\
16295border: none;\
16296resize: none;\
16297outline: none;\
16298overflow: hidden;\
16299font: inherit;\
16300padding: 0 1px;\
16301margin: 0 -1px;\
16302text-indent: -1em;\
16303-ms-user-select: text;\
16304-moz-user-select: text;\
16305-webkit-user-select: text;\
16306user-select: text;\
16307white-space: pre!important;\
16308}\
16309.ace_text-input.ace_composition {\
16310background: inherit;\
16311color: inherit;\
16312z-index: 1000;\
16313opacity: 1;\
16314text-indent: 0;\
16315}\
16316.ace_layer {\
16317z-index: 1;\
16318position: absolute;\
16319overflow: hidden;\
16320word-wrap: normal;\
16321white-space: pre;\
16322height: 100%;\
16323width: 100%;\
16324-moz-box-sizing: border-box;\
16325-webkit-box-sizing: border-box;\
16326box-sizing: border-box;\
16327pointer-events: none;\
16328}\
16329.ace_gutter-layer {\
16330position: relative;\
16331width: auto;\
16332text-align: right;\
16333pointer-events: auto;\
16334}\
16335.ace_text-layer {\
16336font: inherit !important;\
16337}\
16338.ace_cjk {\
16339display: inline-block;\
16340text-align: center;\
16341}\
16342.ace_cursor-layer {\
16343z-index: 4;\
16344}\
16345.ace_cursor {\
16346z-index: 4;\
16347position: absolute;\
16348-moz-box-sizing: border-box;\
16349-webkit-box-sizing: border-box;\
16350box-sizing: border-box;\
16351border-left: 2px solid;\
16352transform: translatez(0);\
16353}\
16354.ace_multiselect .ace_cursor {\
16355border-left-width: 1px;\
16356}\
16357.ace_slim-cursors .ace_cursor {\
16358border-left-width: 1px;\
16359}\
16360.ace_overwrite-cursors .ace_cursor {\
16361border-left-width: 0;\
16362border-bottom: 1px solid;\
16363}\
16364.ace_hidden-cursors .ace_cursor {\
16365opacity: 0.2;\
16366}\
16367.ace_smooth-blinking .ace_cursor {\
16368-webkit-transition: opacity 0.18s;\
16369transition: opacity 0.18s;\
16370}\
16371.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\
16372position: absolute;\
16373z-index: 3;\
16374}\
16375.ace_marker-layer .ace_selection {\
16376position: absolute;\
16377z-index: 5;\
16378}\
16379.ace_marker-layer .ace_bracket {\
16380position: absolute;\
16381z-index: 6;\
16382}\
16383.ace_marker-layer .ace_active-line {\
16384position: absolute;\
16385z-index: 2;\
16386}\
16387.ace_marker-layer .ace_selected-word {\
16388position: absolute;\
16389z-index: 4;\
16390-moz-box-sizing: border-box;\
16391-webkit-box-sizing: border-box;\
16392box-sizing: border-box;\
16393}\
16394.ace_line .ace_fold {\
16395-moz-box-sizing: border-box;\
16396-webkit-box-sizing: border-box;\
16397box-sizing: border-box;\
16398display: inline-block;\
16399height: 11px;\
16400margin-top: -2px;\
16401vertical-align: middle;\
16402background-image:\
16403url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
16404url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\
16405background-repeat: no-repeat, repeat-x;\
16406background-position: center center, top left;\
16407color: transparent;\
16408border: 1px solid black;\
16409border-radius: 2px;\
16410cursor: pointer;\
16411pointer-events: auto;\
16412}\
16413.ace_dark .ace_fold {\
16414}\
16415.ace_fold:hover{\
16416background-image:\
16417url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
16418url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\
16419}\
16420.ace_tooltip {\
16421background-color: #FFF;\
16422background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\
16423background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\
16424border: 1px solid gray;\
16425border-radius: 1px;\
16426box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\
16427color: black;\
16428max-width: 100%;\
16429padding: 3px 4px;\
16430position: fixed;\
16431z-index: 999999;\
16432-moz-box-sizing: border-box;\
16433-webkit-box-sizing: border-box;\
16434box-sizing: border-box;\
16435cursor: default;\
16436white-space: pre;\
16437word-wrap: break-word;\
16438line-height: normal;\
16439font-style: normal;\
16440font-weight: normal;\
16441letter-spacing: normal;\
16442pointer-events: none;\
16443}\
16444.ace_folding-enabled > .ace_gutter-cell {\
16445padding-right: 13px;\
16446}\
16447.ace_fold-widget {\
16448-moz-box-sizing: border-box;\
16449-webkit-box-sizing: border-box;\
16450box-sizing: border-box;\
16451margin: 0 -12px 0 1px;\
16452display: none;\
16453width: 11px;\
16454vertical-align: top;\
16455background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\
16456background-repeat: no-repeat;\
16457background-position: center;\
16458border-radius: 3px;\
16459border: 1px solid transparent;\
16460cursor: pointer;\
16461}\
16462.ace_folding-enabled .ace_fold-widget {\
16463display: inline-block; \
16464}\
16465.ace_fold-widget.ace_end {\
16466background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\
16467}\
16468.ace_fold-widget.ace_closed {\
16469background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\
16470}\
16471.ace_fold-widget:hover {\
16472border: 1px solid rgba(0, 0, 0, 0.3);\
16473background-color: rgba(255, 255, 255, 0.2);\
16474box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
16475}\
16476.ace_fold-widget:active {\
16477border: 1px solid rgba(0, 0, 0, 0.4);\
16478background-color: rgba(0, 0, 0, 0.05);\
16479box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
16480}\
16481.ace_dark .ace_fold-widget {\
16482background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\
16483}\
16484.ace_dark .ace_fold-widget.ace_end {\
16485background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\
16486}\
16487.ace_dark .ace_fold-widget.ace_closed {\
16488background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\
16489}\
16490.ace_dark .ace_fold-widget:hover {\
16491box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
16492background-color: rgba(255, 255, 255, 0.1);\
16493}\
16494.ace_dark .ace_fold-widget:active {\
16495box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
16496}\
16497.ace_fold-widget.ace_invalid {\
16498background-color: #FFB4B4;\
16499border-color: #DE5555;\
16500}\
16501.ace_fade-fold-widgets .ace_fold-widget {\
16502-webkit-transition: opacity 0.4s ease 0.05s;\
16503transition: opacity 0.4s ease 0.05s;\
16504opacity: 0;\
16505}\
16506.ace_fade-fold-widgets:hover .ace_fold-widget {\
16507-webkit-transition: opacity 0.05s ease 0.05s;\
16508transition: opacity 0.05s ease 0.05s;\
16509opacity:1;\
16510}\
16511.ace_underline {\
16512text-decoration: underline;\
16513}\
16514.ace_bold {\
16515font-weight: bold;\
16516}\
16517.ace_nobold .ace_bold {\
16518font-weight: normal;\
16519}\
16520.ace_italic {\
16521font-style: italic;\
16522}\
16523.ace_error-marker {\
16524background-color: rgba(255, 0, 0,0.2);\
16525position: absolute;\
16526z-index: 9;\
16527}\
16528.ace_highlight-marker {\
16529background-color: rgba(255, 255, 0,0.2);\
16530position: absolute;\
16531z-index: 8;\
16532}\
16533.ace_br1 {border-top-left-radius : 3px;}\
16534.ace_br2 {border-top-right-radius : 3px;}\
16535.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}\
16536.ace_br4 {border-bottom-right-radius: 3px;}\
16537.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}\
16538.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}\
16539.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}\
16540.ace_br8 {border-bottom-left-radius : 3px;}\
16541.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}\
16542.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}\
16543.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}\
16544.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16545.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16546.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16547.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16548.ace_text-input-ios {\
16549position: absolute !important;\
16550top: -100000px !important;\
16551left: -100000px !important;\
16552}\
16553";
16554
16555dom.importCssString(editorCss, "ace_editor.css");
16556
16557var VirtualRenderer = function(container, theme) {
16558 var _self = this;
16559
16560 this.container = container || dom.createElement("div");
16561 this.$keepTextAreaAtCursor = !useragent.isOldIE;
16562
16563 dom.addCssClass(this.container, "ace_editor");
16564
16565 this.setTheme(theme);
16566
16567 this.$gutter = dom.createElement("div");
16568 this.$gutter.className = "ace_gutter";
16569 this.container.appendChild(this.$gutter);
16570 this.$gutter.setAttribute("aria-hidden", true);
16571
16572 this.scroller = dom.createElement("div");
16573 this.scroller.className = "ace_scroller";
16574 this.container.appendChild(this.scroller);
16575
16576 this.content = dom.createElement("div");
16577 this.content.className = "ace_content";
16578 this.scroller.appendChild(this.content);
16579
16580 this.$gutterLayer = new GutterLayer(this.$gutter);
16581 this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
16582
16583 this.$markerBack = new MarkerLayer(this.content);
16584
16585 var textLayer = this.$textLayer = new TextLayer(this.content);
16586 this.canvas = textLayer.element;
16587
16588 this.$markerFront = new MarkerLayer(this.content);
16589
16590 this.$cursorLayer = new CursorLayer(this.content);
16591 this.$horizScroll = false;
16592 this.$vScroll = false;
16593
16594 this.scrollBar =
16595 this.scrollBarV = new VScrollBar(this.container, this);
16596 this.scrollBarH = new HScrollBar(this.container, this);
16597 this.scrollBarV.addEventListener("scroll", function(e) {
16598 if (!_self.$scrollAnimation)
16599 _self.session.setScrollTop(e.data - _self.scrollMargin.top);
16600 });
16601 this.scrollBarH.addEventListener("scroll", function(e) {
16602 if (!_self.$scrollAnimation)
16603 _self.session.setScrollLeft(e.data - _self.scrollMargin.left);
16604 });
16605
16606 this.scrollTop = 0;
16607 this.scrollLeft = 0;
16608
16609 this.cursorPos = {
16610 row : 0,
16611 column : 0
16612 };
16613
16614 this.$fontMetrics = new FontMetrics(this.container);
16615 this.$textLayer.$setFontMetrics(this.$fontMetrics);
16616 this.$textLayer.addEventListener("changeCharacterSize", function(e) {
16617 _self.updateCharacterSize();
16618 _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height);
16619 _self._signal("changeCharacterSize", e);
16620 });
16621
16622 this.$size = {
16623 width: 0,
16624 height: 0,
16625 scrollerHeight: 0,
16626 scrollerWidth: 0,
16627 $dirty: true
16628 };
16629
16630 this.layerConfig = {
16631 width : 1,
16632 padding : 0,
16633 firstRow : 0,
16634 firstRowScreen: 0,
16635 lastRow : 0,
16636 lineHeight : 0,
16637 characterWidth : 0,
16638 minHeight : 1,
16639 maxHeight : 1,
16640 offset : 0,
16641 height : 1,
16642 gutterOffset: 1
16643 };
16644
16645 this.scrollMargin = {
16646 left: 0,
16647 right: 0,
16648 top: 0,
16649 bottom: 0,
16650 v: 0,
16651 h: 0
16652 };
16653
16654 this.$loop = new RenderLoop(
16655 this.$renderChanges.bind(this),
16656 this.container.ownerDocument.defaultView
16657 );
16658 this.$loop.schedule(this.CHANGE_FULL);
16659
16660 this.updateCharacterSize();
16661 this.setPadding(4);
16662 config.resetOptions(this);
16663 config._emit("renderer", this);
16664};
16665
16666(function() {
16667
16668 this.CHANGE_CURSOR = 1;
16669 this.CHANGE_MARKER = 2;
16670 this.CHANGE_GUTTER = 4;
16671 this.CHANGE_SCROLL = 8;
16672 this.CHANGE_LINES = 16;
16673 this.CHANGE_TEXT = 32;
16674 this.CHANGE_SIZE = 64;
16675 this.CHANGE_MARKER_BACK = 128;
16676 this.CHANGE_MARKER_FRONT = 256;
16677 this.CHANGE_FULL = 512;
16678 this.CHANGE_H_SCROLL = 1024;
16679
16680 oop.implement(this, EventEmitter);
16681
16682 this.updateCharacterSize = function() {
16683 if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {
16684 this.$allowBoldFonts = this.$textLayer.allowBoldFonts;
16685 this.setStyle("ace_nobold", !this.$allowBoldFonts);
16686 }
16687
16688 this.layerConfig.characterWidth =
16689 this.characterWidth = this.$textLayer.getCharacterWidth();
16690 this.layerConfig.lineHeight =
16691 this.lineHeight = this.$textLayer.getLineHeight();
16692 this.$updatePrintMargin();
16693 };
16694 this.setSession = function(session) {
16695 if (this.session)
16696 this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode);
16697
16698 this.session = session;
16699 if (session && this.scrollMargin.top && session.getScrollTop() <= 0)
16700 session.setScrollTop(-this.scrollMargin.top);
16701
16702 this.$cursorLayer.setSession(session);
16703 this.$markerBack.setSession(session);
16704 this.$markerFront.setSession(session);
16705 this.$gutterLayer.setSession(session);
16706 this.$textLayer.setSession(session);
16707 if (!session)
16708 return;
16709
16710 this.$loop.schedule(this.CHANGE_FULL);
16711 this.session.$setFontMetrics(this.$fontMetrics);
16712 this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;
16713
16714 this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);
16715 this.onChangeNewLineMode();
16716 this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode);
16717 };
16718 this.updateLines = function(firstRow, lastRow, force) {
16719 if (lastRow === undefined)
16720 lastRow = Infinity;
16721
16722 if (!this.$changedLines) {
16723 this.$changedLines = {
16724 firstRow: firstRow,
16725 lastRow: lastRow
16726 };
16727 }
16728 else {
16729 if (this.$changedLines.firstRow > firstRow)
16730 this.$changedLines.firstRow = firstRow;
16731
16732 if (this.$changedLines.lastRow < lastRow)
16733 this.$changedLines.lastRow = lastRow;
16734 }
16735 if (this.$changedLines.lastRow < this.layerConfig.firstRow) {
16736 if (force)
16737 this.$changedLines.lastRow = this.layerConfig.lastRow;
16738 else
16739 return;
16740 }
16741 if (this.$changedLines.firstRow > this.layerConfig.lastRow)
16742 return;
16743 this.$loop.schedule(this.CHANGE_LINES);
16744 };
16745
16746 this.onChangeNewLineMode = function() {
16747 this.$loop.schedule(this.CHANGE_TEXT);
16748 this.$textLayer.$updateEolChar();
16749 this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR);
16750 };
16751
16752 this.onChangeTabSize = function() {
16753 this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);
16754 this.$textLayer.onChangeTabSize();
16755 };
16756 this.updateText = function() {
16757 this.$loop.schedule(this.CHANGE_TEXT);
16758 };
16759 this.updateFull = function(force) {
16760 if (force)
16761 this.$renderChanges(this.CHANGE_FULL, true);
16762 else
16763 this.$loop.schedule(this.CHANGE_FULL);
16764 };
16765 this.updateFontSize = function() {
16766 this.$textLayer.checkForSizeChanges();
16767 };
16768
16769 this.$changes = 0;
16770 this.$updateSizeAsync = function() {
16771 if (this.$loop.pending)
16772 this.$size.$dirty = true;
16773 else
16774 this.onResize();
16775 };
16776 this.onResize = function(force, gutterWidth, width, height) {
16777 if (this.resizing > 2)
16778 return;
16779 else if (this.resizing > 0)
16780 this.resizing++;
16781 else
16782 this.resizing = force ? 1 : 0;
16783 var el = this.container;
16784 if (!height)
16785 height = el.clientHeight || el.scrollHeight;
16786 if (!width)
16787 width = el.clientWidth || el.scrollWidth;
16788 var changes = this.$updateCachedSize(force, gutterWidth, width, height);
16789
16790
16791 if (!this.$size.scrollerHeight || (!width && !height))
16792 return this.resizing = 0;
16793
16794 if (force)
16795 this.$gutterLayer.$padding = null;
16796
16797 if (force)
16798 this.$renderChanges(changes | this.$changes, true);
16799 else
16800 this.$loop.schedule(changes | this.$changes);
16801
16802 if (this.resizing)
16803 this.resizing = 0;
16804 this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null;
16805 };
16806
16807 this.$updateCachedSize = function(force, gutterWidth, width, height) {
16808 height -= (this.$extraHeight || 0);
16809 var changes = 0;
16810 var size = this.$size;
16811 var oldSize = {
16812 width: size.width,
16813 height: size.height,
16814 scrollerHeight: size.scrollerHeight,
16815 scrollerWidth: size.scrollerWidth
16816 };
16817 if (height && (force || size.height != height)) {
16818 size.height = height;
16819 changes |= this.CHANGE_SIZE;
16820
16821 size.scrollerHeight = size.height;
16822 if (this.$horizScroll)
16823 size.scrollerHeight -= this.scrollBarH.getHeight();
16824 this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px";
16825
16826 changes = changes | this.CHANGE_SCROLL;
16827 }
16828
16829 if (width && (force || size.width != width)) {
16830 changes |= this.CHANGE_SIZE;
16831 size.width = width;
16832
16833 if (gutterWidth == null)
16834 gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
16835
16836 this.gutterWidth = gutterWidth;
16837
16838 this.scrollBarH.element.style.left =
16839 this.scroller.style.left = gutterWidth + "px";
16840 size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());
16841
16842 this.scrollBarH.element.style.right =
16843 this.scroller.style.right = this.scrollBarV.getWidth() + "px";
16844 this.scroller.style.bottom = this.scrollBarH.getHeight() + "px";
16845
16846 if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
16847 changes |= this.CHANGE_FULL;
16848 }
16849
16850 size.$dirty = !width || !height;
16851
16852 if (changes)
16853 this._signal("resize", oldSize);
16854
16855 return changes;
16856 };
16857
16858 this.onGutterResize = function() {
16859 var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
16860 if (gutterWidth != this.gutterWidth)
16861 this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
16862
16863 if (this.session.getUseWrapMode() && this.adjustWrapLimit()) {
16864 this.$loop.schedule(this.CHANGE_FULL);
16865 } else if (this.$size.$dirty) {
16866 this.$loop.schedule(this.CHANGE_FULL);
16867 } else {
16868 this.$computeLayerConfig();
16869 this.$loop.schedule(this.CHANGE_MARKER);
16870 }
16871 };
16872 this.adjustWrapLimit = function() {
16873 var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
16874 var limit = Math.floor(availableWidth / this.characterWidth);
16875 return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn);
16876 };
16877 this.setAnimatedScroll = function(shouldAnimate){
16878 this.setOption("animatedScroll", shouldAnimate);
16879 };
16880 this.getAnimatedScroll = function() {
16881 return this.$animatedScroll;
16882 };
16883 this.setShowInvisibles = function(showInvisibles) {
16884 this.setOption("showInvisibles", showInvisibles);
16885 this.session.$bidiHandler.setShowInvisibles(showInvisibles);
16886 };
16887 this.getShowInvisibles = function() {
16888 return this.getOption("showInvisibles");
16889 };
16890 this.getDisplayIndentGuides = function() {
16891 return this.getOption("displayIndentGuides");
16892 };
16893
16894 this.setDisplayIndentGuides = function(display) {
16895 this.setOption("displayIndentGuides", display);
16896 };
16897 this.setShowPrintMargin = function(showPrintMargin) {
16898 this.setOption("showPrintMargin", showPrintMargin);
16899 };
16900 this.getShowPrintMargin = function() {
16901 return this.getOption("showPrintMargin");
16902 };
16903 this.setPrintMarginColumn = function(showPrintMargin) {
16904 this.setOption("printMarginColumn", showPrintMargin);
16905 };
16906 this.getPrintMarginColumn = function() {
16907 return this.getOption("printMarginColumn");
16908 };
16909 this.getShowGutter = function(){
16910 return this.getOption("showGutter");
16911 };
16912 this.setShowGutter = function(show){
16913 return this.setOption("showGutter", show);
16914 };
16915
16916 this.getFadeFoldWidgets = function(){
16917 return this.getOption("fadeFoldWidgets");
16918 };
16919
16920 this.setFadeFoldWidgets = function(show) {
16921 this.setOption("fadeFoldWidgets", show);
16922 };
16923
16924 this.setHighlightGutterLine = function(shouldHighlight) {
16925 this.setOption("highlightGutterLine", shouldHighlight);
16926 };
16927
16928 this.getHighlightGutterLine = function() {
16929 return this.getOption("highlightGutterLine");
16930 };
16931
16932 this.$updateGutterLineHighlight = function() {
16933 var pos = this.$cursorLayer.$pixelPos;
16934 var height = this.layerConfig.lineHeight;
16935 if (this.session.getUseWrapMode()) {
16936 var cursor = this.session.selection.getCursor();
16937 cursor.column = 0;
16938 pos = this.$cursorLayer.getPixelPosition(cursor, true);
16939 height *= this.session.getRowLength(cursor.row);
16940 }
16941 this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px";
16942 this.$gutterLineHighlight.style.height = height + "px";
16943 };
16944
16945 this.$updatePrintMargin = function() {
16946 if (!this.$showPrintMargin && !this.$printMarginEl)
16947 return;
16948
16949 if (!this.$printMarginEl) {
16950 var containerEl = dom.createElement("div");
16951 containerEl.className = "ace_layer ace_print-margin-layer";
16952 this.$printMarginEl = dom.createElement("div");
16953 this.$printMarginEl.className = "ace_print-margin";
16954 containerEl.appendChild(this.$printMarginEl);
16955 this.content.insertBefore(containerEl, this.content.firstChild);
16956 }
16957
16958 var style = this.$printMarginEl.style;
16959 style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px";
16960 style.visibility = this.$showPrintMargin ? "visible" : "hidden";
16961
16962 if (this.session && this.session.$wrap == -1)
16963 this.adjustWrapLimit();
16964 };
16965 this.getContainerElement = function() {
16966 return this.container;
16967 };
16968 this.getMouseEventTarget = function() {
16969 return this.scroller;
16970 };
16971 this.getTextAreaContainer = function() {
16972 return this.container;
16973 };
16974 this.$moveTextAreaToCursor = function() {
16975 if (!this.$keepTextAreaAtCursor)
16976 return;
16977 var config = this.layerConfig;
16978 var posTop = this.$cursorLayer.$pixelPos.top;
16979 var posLeft = this.$cursorLayer.$pixelPos.left;
16980 posTop -= config.offset;
16981
16982 var style = this.textarea.style;
16983 var h = this.lineHeight;
16984 if (posTop < 0 || posTop > config.height - h) {
16985 style.top = style.left = "0";
16986 return;
16987 }
16988
16989 var w = this.characterWidth;
16990 if (this.$composition) {
16991 var val = this.textarea.value.replace(/^\x01+/, "");
16992 w *= (this.session.$getStringScreenWidth(val)[0]+2);
16993 h += 2;
16994 }
16995 posLeft -= this.scrollLeft;
16996 if (posLeft > this.$size.scrollerWidth - w)
16997 posLeft = this.$size.scrollerWidth - w;
16998
16999 posLeft += this.gutterWidth;
17000 style.height = h + "px";
17001 style.width = w + "px";
17002 style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + "px";
17003 style.top = Math.min(posTop, this.$size.height - h) + "px";
17004 };
17005 this.getFirstVisibleRow = function() {
17006 return this.layerConfig.firstRow;
17007 };
17008 this.getFirstFullyVisibleRow = function() {
17009 return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
17010 };
17011 this.getLastFullyVisibleRow = function() {
17012 var config = this.layerConfig;
17013 var lastRow = config.lastRow;
17014 var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight;
17015 if (top - this.session.getScrollTop() > config.height - config.lineHeight)
17016 return lastRow - 1;
17017 return lastRow;
17018 };
17019 this.getLastVisibleRow = function() {
17020 return this.layerConfig.lastRow;
17021 };
17022
17023 this.$padding = null;
17024 this.setPadding = function(padding) {
17025 this.$padding = padding;
17026 this.$textLayer.setPadding(padding);
17027 this.$cursorLayer.setPadding(padding);
17028 this.$markerFront.setPadding(padding);
17029 this.$markerBack.setPadding(padding);
17030 this.$loop.schedule(this.CHANGE_FULL);
17031 this.$updatePrintMargin();
17032 };
17033
17034 this.setScrollMargin = function(top, bottom, left, right) {
17035 var sm = this.scrollMargin;
17036 sm.top = top|0;
17037 sm.bottom = bottom|0;
17038 sm.right = right|0;
17039 sm.left = left|0;
17040 sm.v = sm.top + sm.bottom;
17041 sm.h = sm.left + sm.right;
17042 if (sm.top && this.scrollTop <= 0 && this.session)
17043 this.session.setScrollTop(-sm.top);
17044 this.updateFull();
17045 };
17046 this.getHScrollBarAlwaysVisible = function() {
17047 return this.$hScrollBarAlwaysVisible;
17048 };
17049 this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
17050 this.setOption("hScrollBarAlwaysVisible", alwaysVisible);
17051 };
17052 this.getVScrollBarAlwaysVisible = function() {
17053 return this.$vScrollBarAlwaysVisible;
17054 };
17055 this.setVScrollBarAlwaysVisible = function(alwaysVisible) {
17056 this.setOption("vScrollBarAlwaysVisible", alwaysVisible);
17057 };
17058
17059 this.$updateScrollBarV = function() {
17060 var scrollHeight = this.layerConfig.maxHeight;
17061 var scrollerHeight = this.$size.scrollerHeight;
17062 if (!this.$maxLines && this.$scrollPastEnd) {
17063 scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd;
17064 if (this.scrollTop > scrollHeight - scrollerHeight) {
17065 scrollHeight = this.scrollTop + scrollerHeight;
17066 this.scrollBarV.scrollTop = null;
17067 }
17068 }
17069 this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v);
17070 this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);
17071 };
17072 this.$updateScrollBarH = function() {
17073 this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);
17074 this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);
17075 };
17076
17077 this.$frozen = false;
17078 this.freeze = function() {
17079 this.$frozen = true;
17080 };
17081
17082 this.unfreeze = function() {
17083 this.$frozen = false;
17084 };
17085
17086 this.$renderChanges = function(changes, force) {
17087 if (this.$changes) {
17088 changes |= this.$changes;
17089 this.$changes = 0;
17090 }
17091 if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) {
17092 this.$changes |= changes;
17093 return;
17094 }
17095 if (this.$size.$dirty) {
17096 this.$changes |= changes;
17097 return this.onResize(true);
17098 }
17099 if (!this.lineHeight) {
17100 this.$textLayer.checkForSizeChanges();
17101 }
17102
17103 this._signal("beforeRender");
17104
17105 if (this.session && this.session.$bidiHandler)
17106 this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);
17107
17108 var config = this.layerConfig;
17109 if (changes & this.CHANGE_FULL ||
17110 changes & this.CHANGE_SIZE ||
17111 changes & this.CHANGE_TEXT ||
17112 changes & this.CHANGE_LINES ||
17113 changes & this.CHANGE_SCROLL ||
17114 changes & this.CHANGE_H_SCROLL
17115 ) {
17116 changes |= this.$computeLayerConfig();
17117 if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) {
17118 var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight;
17119 if (st > 0) {
17120 this.scrollTop = st;
17121 changes = changes | this.CHANGE_SCROLL;
17122 changes |= this.$computeLayerConfig();
17123 }
17124 }
17125 config = this.layerConfig;
17126 this.$updateScrollBarV();
17127 if (changes & this.CHANGE_H_SCROLL)
17128 this.$updateScrollBarH();
17129 this.$gutterLayer.element.style.marginTop = (-config.offset) + "px";
17130 this.content.style.marginTop = (-config.offset) + "px";
17131 this.content.style.width = config.width + 2 * this.$padding + "px";
17132 this.content.style.height = config.minHeight + "px";
17133 }
17134 if (changes & this.CHANGE_H_SCROLL) {
17135 this.content.style.marginLeft = -this.scrollLeft + "px";
17136 this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
17137 }
17138 if (changes & this.CHANGE_FULL) {
17139 this.$textLayer.update(config);
17140 if (this.$showGutter)
17141 this.$gutterLayer.update(config);
17142 this.$markerBack.update(config);
17143 this.$markerFront.update(config);
17144 this.$cursorLayer.update(config);
17145 this.$moveTextAreaToCursor();
17146 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17147 this._signal("afterRender");
17148 return;
17149 }
17150 if (changes & this.CHANGE_SCROLL) {
17151 if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
17152 this.$textLayer.update(config);
17153 else
17154 this.$textLayer.scrollLines(config);
17155
17156 if (this.$showGutter)
17157 this.$gutterLayer.update(config);
17158 this.$markerBack.update(config);
17159 this.$markerFront.update(config);
17160 this.$cursorLayer.update(config);
17161 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17162 this.$moveTextAreaToCursor();
17163 this._signal("afterRender");
17164 return;
17165 }
17166
17167 if (changes & this.CHANGE_TEXT) {
17168 this.$textLayer.update(config);
17169 if (this.$showGutter)
17170 this.$gutterLayer.update(config);
17171 }
17172 else if (changes & this.CHANGE_LINES) {
17173 if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
17174 this.$gutterLayer.update(config);
17175 }
17176 else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
17177 if (this.$showGutter)
17178 this.$gutterLayer.update(config);
17179 }
17180
17181 if (changes & this.CHANGE_CURSOR) {
17182 this.$cursorLayer.update(config);
17183 this.$moveTextAreaToCursor();
17184 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17185 }
17186
17187 if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
17188 this.$markerFront.update(config);
17189 }
17190
17191 if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
17192 this.$markerBack.update(config);
17193 }
17194
17195 this._signal("afterRender");
17196 };
17197
17198
17199 this.$autosize = function() {
17200 var height = this.session.getScreenLength() * this.lineHeight;
17201 var maxHeight = this.$maxLines * this.lineHeight;
17202 var desiredHeight = Math.min(maxHeight,
17203 Math.max((this.$minLines || 1) * this.lineHeight, height)
17204 ) + this.scrollMargin.v + (this.$extraHeight || 0);
17205 if (this.$horizScroll)
17206 desiredHeight += this.scrollBarH.getHeight();
17207 if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight)
17208 desiredHeight = this.$maxPixelHeight;
17209 var vScroll = height > maxHeight;
17210
17211 if (desiredHeight != this.desiredHeight ||
17212 this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {
17213 if (vScroll != this.$vScroll) {
17214 this.$vScroll = vScroll;
17215 this.scrollBarV.setVisible(vScroll);
17216 }
17217
17218 var w = this.container.clientWidth;
17219 this.container.style.height = desiredHeight + "px";
17220 this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);
17221 this.desiredHeight = desiredHeight;
17222
17223 this._signal("autosize");
17224 }
17225 };
17226
17227 this.$computeLayerConfig = function() {
17228 var session = this.session;
17229 var size = this.$size;
17230
17231 var hideScrollbars = size.height <= 2 * this.lineHeight;
17232 var screenLines = this.session.getScreenLength();
17233 var maxHeight = screenLines * this.lineHeight;
17234
17235 var longestLine = this.$getLongestLine();
17236
17237 var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||
17238 size.scrollerWidth - longestLine - 2 * this.$padding < 0);
17239
17240 var hScrollChanged = this.$horizScroll !== horizScroll;
17241 if (hScrollChanged) {
17242 this.$horizScroll = horizScroll;
17243 this.scrollBarH.setVisible(horizScroll);
17244 }
17245 var vScrollBefore = this.$vScroll; // autosize can change vscroll value in which case we need to update longestLine
17246 if (this.$maxLines && this.lineHeight > 1)
17247 this.$autosize();
17248
17249 var offset = this.scrollTop % this.lineHeight;
17250 var minHeight = size.scrollerHeight + this.lineHeight;
17251
17252 var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd
17253 ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd
17254 : 0;
17255 maxHeight += scrollPastEnd;
17256
17257 var sm = this.scrollMargin;
17258 this.session.setScrollTop(Math.max(-sm.top,
17259 Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom)));
17260
17261 this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft,
17262 longestLine + 2 * this.$padding - size.scrollerWidth + sm.right)));
17263
17264 var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||
17265 size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top);
17266 var vScrollChanged = vScrollBefore !== vScroll;
17267 if (vScrollChanged) {
17268 this.$vScroll = vScroll;
17269 this.scrollBarV.setVisible(vScroll);
17270 }
17271
17272 var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
17273 var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
17274 var lastRow = firstRow + lineCount;
17275 var firstRowScreen, firstRowHeight;
17276 var lineHeight = this.lineHeight;
17277 firstRow = session.screenToDocumentRow(firstRow, 0);
17278 var foldLine = session.getFoldLine(firstRow);
17279 if (foldLine) {
17280 firstRow = foldLine.start.row;
17281 }
17282
17283 firstRowScreen = session.documentToScreenRow(firstRow, 0);
17284 firstRowHeight = session.getRowLength(firstRow) * lineHeight;
17285
17286 lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);
17287 minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +
17288 firstRowHeight;
17289
17290 offset = this.scrollTop - firstRowScreen * lineHeight;
17291
17292 var changes = 0;
17293 if (this.layerConfig.width != longestLine)
17294 changes = this.CHANGE_H_SCROLL;
17295 if (hScrollChanged || vScrollChanged) {
17296 changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height);
17297 this._signal("scrollbarVisibilityChanged");
17298 if (vScrollChanged)
17299 longestLine = this.$getLongestLine();
17300 }
17301
17302 this.layerConfig = {
17303 width : longestLine,
17304 padding : this.$padding,
17305 firstRow : firstRow,
17306 firstRowScreen: firstRowScreen,
17307 lastRow : lastRow,
17308 lineHeight : lineHeight,
17309 characterWidth : this.characterWidth,
17310 minHeight : minHeight,
17311 maxHeight : maxHeight,
17312 offset : offset,
17313 gutterOffset : lineHeight ? Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)) : 0,
17314 height : this.$size.scrollerHeight
17315 };
17316
17317 return changes;
17318 };
17319
17320 this.$updateLines = function() {
17321 if (!this.$changedLines) return;
17322 var firstRow = this.$changedLines.firstRow;
17323 var lastRow = this.$changedLines.lastRow;
17324 this.$changedLines = null;
17325
17326 var layerConfig = this.layerConfig;
17327
17328 if (firstRow > layerConfig.lastRow + 1) { return; }
17329 if (lastRow < layerConfig.firstRow) { return; }
17330 if (lastRow === Infinity) {
17331 if (this.$showGutter)
17332 this.$gutterLayer.update(layerConfig);
17333 this.$textLayer.update(layerConfig);
17334 return;
17335 }
17336 this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
17337 return true;
17338 };
17339
17340 this.$getLongestLine = function() {
17341 var charCount = this.session.getScreenWidth();
17342 if (this.showInvisibles && !this.session.$useWrapMode)
17343 charCount += 1;
17344
17345 return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
17346 };
17347 this.updateFrontMarkers = function() {
17348 this.$markerFront.setMarkers(this.session.getMarkers(true));
17349 this.$loop.schedule(this.CHANGE_MARKER_FRONT);
17350 };
17351 this.updateBackMarkers = function() {
17352 this.$markerBack.setMarkers(this.session.getMarkers());
17353 this.$loop.schedule(this.CHANGE_MARKER_BACK);
17354 };
17355 this.addGutterDecoration = function(row, className){
17356 this.$gutterLayer.addGutterDecoration(row, className);
17357 };
17358 this.removeGutterDecoration = function(row, className){
17359 this.$gutterLayer.removeGutterDecoration(row, className);
17360 };
17361 this.updateBreakpoints = function(rows) {
17362 this.$loop.schedule(this.CHANGE_GUTTER);
17363 };
17364 this.setAnnotations = function(annotations) {
17365 this.$gutterLayer.setAnnotations(annotations);
17366 this.$loop.schedule(this.CHANGE_GUTTER);
17367 };
17368 this.updateCursor = function() {
17369 this.$loop.schedule(this.CHANGE_CURSOR);
17370 };
17371 this.hideCursor = function() {
17372 this.$cursorLayer.hideCursor();
17373 };
17374 this.showCursor = function() {
17375 this.$cursorLayer.showCursor();
17376 };
17377
17378 this.scrollSelectionIntoView = function(anchor, lead, offset) {
17379 this.scrollCursorIntoView(anchor, offset);
17380 this.scrollCursorIntoView(lead, offset);
17381 };
17382 this.scrollCursorIntoView = function(cursor, offset, $viewMargin) {
17383 if (this.$size.scrollerHeight === 0)
17384 return;
17385
17386 var pos = this.$cursorLayer.getPixelPosition(cursor);
17387
17388 var left = pos.left;
17389 var top = pos.top;
17390
17391 var topMargin = $viewMargin && $viewMargin.top || 0;
17392 var bottomMargin = $viewMargin && $viewMargin.bottom || 0;
17393
17394 var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
17395
17396 if (scrollTop + topMargin > top) {
17397 if (offset && scrollTop + topMargin > top + this.lineHeight)
17398 top -= offset * this.$size.scrollerHeight;
17399 if (top === 0)
17400 top = -this.scrollMargin.top;
17401 this.session.setScrollTop(top);
17402 } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) {
17403 if (offset && scrollTop + this.$size.scrollerHeight - bottomMargin < top - this.lineHeight)
17404 top += offset * this.$size.scrollerHeight;
17405 this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
17406 }
17407
17408 var scrollLeft = this.scrollLeft;
17409
17410 if (scrollLeft > left) {
17411 if (left < this.$padding + 2 * this.layerConfig.characterWidth)
17412 left = -this.scrollMargin.left;
17413 this.session.setScrollLeft(left);
17414 } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
17415 this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
17416 } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {
17417 this.session.setScrollLeft(0);
17418 }
17419 };
17420 this.getScrollTop = function() {
17421 return this.session.getScrollTop();
17422 };
17423 this.getScrollLeft = function() {
17424 return this.session.getScrollLeft();
17425 };
17426 this.getScrollTopRow = function() {
17427 return this.scrollTop / this.lineHeight;
17428 };
17429 this.getScrollBottomRow = function() {
17430 return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
17431 };
17432 this.scrollToRow = function(row) {
17433 this.session.setScrollTop(row * this.lineHeight);
17434 };
17435
17436 this.alignCursor = function(cursor, alignment) {
17437 if (typeof cursor == "number")
17438 cursor = {row: cursor, column: 0};
17439
17440 var pos = this.$cursorLayer.getPixelPosition(cursor);
17441 var h = this.$size.scrollerHeight - this.lineHeight;
17442 var offset = pos.top - h * (alignment || 0);
17443
17444 this.session.setScrollTop(offset);
17445 return offset;
17446 };
17447
17448 this.STEPS = 8;
17449 this.$calcSteps = function(fromValue, toValue){
17450 var i = 0;
17451 var l = this.STEPS;
17452 var steps = [];
17453
17454 var func = function(t, x_min, dx) {
17455 return dx * (Math.pow(t - 1, 3) + 1) + x_min;
17456 };
17457
17458 for (i = 0; i < l; ++i)
17459 steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
17460
17461 return steps;
17462 };
17463 this.scrollToLine = function(line, center, animate, callback) {
17464 var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
17465 var offset = pos.top;
17466 if (center)
17467 offset -= this.$size.scrollerHeight / 2;
17468
17469 var initialScroll = this.scrollTop;
17470 this.session.setScrollTop(offset);
17471 if (animate !== false)
17472 this.animateScrolling(initialScroll, callback);
17473 };
17474
17475 this.animateScrolling = function(fromValue, callback) {
17476 var toValue = this.scrollTop;
17477 if (!this.$animatedScroll)
17478 return;
17479 var _self = this;
17480
17481 if (fromValue == toValue)
17482 return;
17483
17484 if (this.$scrollAnimation) {
17485 var oldSteps = this.$scrollAnimation.steps;
17486 if (oldSteps.length) {
17487 fromValue = oldSteps[0];
17488 if (fromValue == toValue)
17489 return;
17490 }
17491 }
17492
17493 var steps = _self.$calcSteps(fromValue, toValue);
17494 this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};
17495
17496 clearInterval(this.$timer);
17497
17498 _self.session.setScrollTop(steps.shift());
17499 _self.session.$scrollTop = toValue;
17500 this.$timer = setInterval(function() {
17501 if (steps.length) {
17502 _self.session.setScrollTop(steps.shift());
17503 _self.session.$scrollTop = toValue;
17504 } else if (toValue != null) {
17505 _self.session.$scrollTop = -1;
17506 _self.session.setScrollTop(toValue);
17507 toValue = null;
17508 } else {
17509 _self.$timer = clearInterval(_self.$timer);
17510 _self.$scrollAnimation = null;
17511 callback && callback();
17512 }
17513 }, 10);
17514 };
17515 this.scrollToY = function(scrollTop) {
17516 if (this.scrollTop !== scrollTop) {
17517 this.$loop.schedule(this.CHANGE_SCROLL);
17518 this.scrollTop = scrollTop;
17519 }
17520 };
17521 this.scrollToX = function(scrollLeft) {
17522 if (this.scrollLeft !== scrollLeft)
17523 this.scrollLeft = scrollLeft;
17524 this.$loop.schedule(this.CHANGE_H_SCROLL);
17525 };
17526 this.scrollTo = function(x, y) {
17527 this.session.setScrollTop(y);
17528 this.session.setScrollLeft(y);
17529 };
17530 this.scrollBy = function(deltaX, deltaY) {
17531 deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
17532 deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
17533 };
17534 this.isScrollableBy = function(deltaX, deltaY) {
17535 if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)
17536 return true;
17537 if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight
17538 - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)
17539 return true;
17540 if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left)
17541 return true;
17542 if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth
17543 - this.layerConfig.width < -1 + this.scrollMargin.right)
17544 return true;
17545 };
17546
17547 this.pixelToScreenCoordinates = function(x, y) {
17548 var canvasPos = this.scroller.getBoundingClientRect();
17549
17550 var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;
17551 var offset = offsetX / this.characterWidth;
17552 var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
17553 var col = Math.round(offset);
17554
17555 return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX: offsetX};
17556 };
17557
17558 this.screenToTextCoordinates = function(x, y) {
17559 var canvasPos = this.scroller.getBoundingClientRect();
17560 var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;
17561
17562 var col = Math.round(offsetX / this.characterWidth);
17563
17564 var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight;
17565
17566 return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX);
17567 };
17568 this.textToScreenCoordinates = function(row, column) {
17569 var canvasPos = this.scroller.getBoundingClientRect();
17570 var pos = this.session.documentToScreenPosition(row, column);
17571
17572 var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row)
17573 ? this.session.$bidiHandler.getPosLeft(pos.column)
17574 : Math.round(pos.column * this.characterWidth));
17575
17576 var y = pos.row * this.lineHeight;
17577
17578 return {
17579 pageX: canvasPos.left + x - this.scrollLeft,
17580 pageY: canvasPos.top + y - this.scrollTop
17581 };
17582 };
17583 this.visualizeFocus = function() {
17584 dom.addCssClass(this.container, "ace_focus");
17585 };
17586 this.visualizeBlur = function() {
17587 dom.removeCssClass(this.container, "ace_focus");
17588 };
17589 this.showComposition = function(position) {
17590 if (!this.$composition)
17591 this.$composition = {
17592 keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
17593 cssText: this.textarea.style.cssText
17594 };
17595
17596 this.$keepTextAreaAtCursor = true;
17597 dom.addCssClass(this.textarea, "ace_composition");
17598 this.textarea.style.cssText = "";
17599 this.$moveTextAreaToCursor();
17600 };
17601 this.setCompositionText = function(text) {
17602 this.$moveTextAreaToCursor();
17603 };
17604 this.hideComposition = function() {
17605 if (!this.$composition)
17606 return;
17607
17608 dom.removeCssClass(this.textarea, "ace_composition");
17609 this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;
17610 this.textarea.style.cssText = this.$composition.cssText;
17611 this.$composition = null;
17612 };
17613 this.setTheme = function(theme, cb) {
17614 var _self = this;
17615 this.$themeId = theme;
17616 _self._dispatchEvent('themeChange',{theme:theme});
17617
17618 if (!theme || typeof theme == "string") {
17619 var moduleName = theme || this.$options.theme.initialValue;
17620 config.loadModule(["theme", moduleName], afterLoad);
17621 } else {
17622 afterLoad(theme);
17623 }
17624
17625 function afterLoad(module) {
17626 if (_self.$themeId != theme)
17627 return cb && cb();
17628 if (!module || !module.cssClass)
17629 throw new Error("couldn't load module " + theme + " or it didn't call define");
17630 dom.importCssString(
17631 module.cssText,
17632 module.cssClass,
17633 _self.container.ownerDocument
17634 );
17635
17636 if (_self.theme)
17637 dom.removeCssClass(_self.container, _self.theme.cssClass);
17638
17639 var padding = "padding" in module ? module.padding
17640 : "padding" in (_self.theme || {}) ? 4 : _self.$padding;
17641 if (_self.$padding && padding != _self.$padding)
17642 _self.setPadding(padding);
17643 _self.$theme = module.cssClass;
17644
17645 _self.theme = module;
17646 dom.addCssClass(_self.container, module.cssClass);
17647 dom.setCssClass(_self.container, "ace_dark", module.isDark);
17648 if (_self.$size) {
17649 _self.$size.width = 0;
17650 _self.$updateSizeAsync();
17651 }
17652
17653 _self._dispatchEvent('themeLoaded', {theme:module});
17654 cb && cb();
17655 }
17656 };
17657 this.getTheme = function() {
17658 return this.$themeId;
17659 };
17660 this.setStyle = function(style, include) {
17661 dom.setCssClass(this.container, style, include !== false);
17662 };
17663 this.unsetStyle = function(style) {
17664 dom.removeCssClass(this.container, style);
17665 };
17666
17667 this.setCursorStyle = function(style) {
17668 if (this.scroller.style.cursor != style)
17669 this.scroller.style.cursor = style;
17670 };
17671 this.setMouseCursor = function(cursorStyle) {
17672 this.scroller.style.cursor = cursorStyle;
17673 };
17674 this.destroy = function() {
17675 this.$textLayer.destroy();
17676 this.$cursorLayer.destroy();
17677 };
17678
17679}).call(VirtualRenderer.prototype);
17680
17681
17682config.defineOptions(VirtualRenderer.prototype, "renderer", {
17683 animatedScroll: {initialValue: false},
17684 showInvisibles: {
17685 set: function(value) {
17686 if (this.$textLayer.setShowInvisibles(value))
17687 this.$loop.schedule(this.CHANGE_TEXT);
17688 },
17689 initialValue: false
17690 },
17691 showPrintMargin: {
17692 set: function() { this.$updatePrintMargin(); },
17693 initialValue: true
17694 },
17695 printMarginColumn: {
17696 set: function() { this.$updatePrintMargin(); },
17697 initialValue: 80
17698 },
17699 printMargin: {
17700 set: function(val) {
17701 if (typeof val == "number")
17702 this.$printMarginColumn = val;
17703 this.$showPrintMargin = !!val;
17704 this.$updatePrintMargin();
17705 },
17706 get: function() {
17707 return this.$showPrintMargin && this.$printMarginColumn;
17708 }
17709 },
17710 showGutter: {
17711 set: function(show){
17712 this.$gutter.style.display = show ? "block" : "none";
17713 this.$loop.schedule(this.CHANGE_FULL);
17714 this.onGutterResize();
17715 },
17716 initialValue: true
17717 },
17718 fadeFoldWidgets: {
17719 set: function(show) {
17720 dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
17721 },
17722 initialValue: false
17723 },
17724 showFoldWidgets: {
17725 set: function(show) {this.$gutterLayer.setShowFoldWidgets(show);},
17726 initialValue: true
17727 },
17728 showLineNumbers: {
17729 set: function(show) {
17730 this.$gutterLayer.setShowLineNumbers(show);
17731 this.$loop.schedule(this.CHANGE_GUTTER);
17732 },
17733 initialValue: true
17734 },
17735 displayIndentGuides: {
17736 set: function(show) {
17737 if (this.$textLayer.setDisplayIndentGuides(show))
17738 this.$loop.schedule(this.CHANGE_TEXT);
17739 },
17740 initialValue: true
17741 },
17742 highlightGutterLine: {
17743 set: function(shouldHighlight) {
17744 if (!this.$gutterLineHighlight) {
17745 this.$gutterLineHighlight = dom.createElement("div");
17746 this.$gutterLineHighlight.className = "ace_gutter-active-line";
17747 this.$gutter.appendChild(this.$gutterLineHighlight);
17748 return;
17749 }
17750
17751 this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
17752 if (this.$cursorLayer.$pixelPos)
17753 this.$updateGutterLineHighlight();
17754 },
17755 initialValue: false,
17756 value: true
17757 },
17758 hScrollBarAlwaysVisible: {
17759 set: function(val) {
17760 if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)
17761 this.$loop.schedule(this.CHANGE_SCROLL);
17762 },
17763 initialValue: false
17764 },
17765 vScrollBarAlwaysVisible: {
17766 set: function(val) {
17767 if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)
17768 this.$loop.schedule(this.CHANGE_SCROLL);
17769 },
17770 initialValue: false
17771 },
17772 fontSize: {
17773 set: function(size) {
17774 if (typeof size == "number")
17775 size = size + "px";
17776 this.container.style.fontSize = size;
17777 this.updateFontSize();
17778 },
17779 initialValue: 12
17780 },
17781 fontFamily: {
17782 set: function(name) {
17783 this.container.style.fontFamily = name;
17784 this.updateFontSize();
17785 }
17786 },
17787 maxLines: {
17788 set: function(val) {
17789 this.updateFull();
17790 }
17791 },
17792 minLines: {
17793 set: function(val) {
17794 this.updateFull();
17795 }
17796 },
17797 maxPixelHeight: {
17798 set: function(val) {
17799 this.updateFull();
17800 },
17801 initialValue: 0
17802 },
17803 scrollPastEnd: {
17804 set: function(val) {
17805 val = +val || 0;
17806 if (this.$scrollPastEnd == val)
17807 return;
17808 this.$scrollPastEnd = val;
17809 this.$loop.schedule(this.CHANGE_SCROLL);
17810 },
17811 initialValue: 0,
17812 handlesSet: true
17813 },
17814 fixedWidthGutter: {
17815 set: function(val) {
17816 this.$gutterLayer.$fixedWidth = !!val;
17817 this.$loop.schedule(this.CHANGE_GUTTER);
17818 }
17819 },
17820 theme: {
17821 set: function(val) { this.setTheme(val); },
17822 get: function() { return this.$themeId || this.theme; },
17823 initialValue: "./theme/textmate",
17824 handlesSet: true
17825 }
17826});
17827
17828exports.VirtualRenderer = VirtualRenderer;
17829});
17830
17831ace.define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"], function(acequire, exports, module) {
17832
17833var oop = acequire("../lib/oop");
17834var net = acequire("../lib/net");
17835var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
17836var config = acequire("../config");
17837
17838function $workerBlob(workerUrl, mod) {
17839 var script = mod.src;"importScripts('" + net.qualifyURL(workerUrl) + "');";
17840 try {
17841 return new Blob([script], {"type": "application/javascript"});
17842 } catch (e) { // Backwards-compatibility
17843 var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
17844 var blobBuilder = new BlobBuilder();
17845 blobBuilder.append(script);
17846 return blobBuilder.getBlob("application/javascript");
17847 }
17848}
17849
17850function createWorker(workerUrl, mod) {
17851 var blob = $workerBlob(workerUrl, mod);
17852 var URL = window.URL || window.webkitURL;
17853 var blobURL = URL.createObjectURL(blob);
17854 return new Worker(blobURL);
17855}
17856
17857var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl, importScripts) {
17858 this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
17859 this.changeListener = this.changeListener.bind(this);
17860 this.onMessage = this.onMessage.bind(this);
17861 if (acequire.nameToUrl && !acequire.toUrl)
17862 acequire.toUrl = acequire.nameToUrl;
17863
17864 if (config.get("packaged") || !acequire.toUrl) {
17865 workerUrl = workerUrl || config.moduleUrl(mod.id, "worker");
17866 } else {
17867 var normalizePath = this.$normalizePath;
17868 workerUrl = workerUrl || normalizePath(acequire.toUrl("ace/worker/worker.js", null, "_"));
17869
17870 var tlns = {};
17871 topLevelNamespaces.forEach(function(ns) {
17872 tlns[ns] = normalizePath(acequire.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, ""));
17873 });
17874 }
17875
17876 this.$worker = createWorker(workerUrl, mod);
17877 if (importScripts) {
17878 this.send("importScripts", importScripts);
17879 }
17880 this.$worker.postMessage({
17881 init : true,
17882 tlns : tlns,
17883 module : mod.id,
17884 classname : classname
17885 });
17886
17887 this.callbackId = 1;
17888 this.callbacks = {};
17889
17890 this.$worker.onmessage = this.onMessage;
17891};
17892
17893(function(){
17894
17895 oop.implement(this, EventEmitter);
17896
17897 this.onMessage = function(e) {
17898 var msg = e.data;
17899 switch (msg.type) {
17900 case "event":
17901 this._signal(msg.name, {data: msg.data});
17902 break;
17903 case "call":
17904 var callback = this.callbacks[msg.id];
17905 if (callback) {
17906 callback(msg.data);
17907 delete this.callbacks[msg.id];
17908 }
17909 break;
17910 case "error":
17911 this.reportError(msg.data);
17912 break;
17913 case "log":
17914 window.console && console.log && console.log.apply(console, msg.data);
17915 break;
17916 }
17917 };
17918
17919 this.reportError = function(err) {
17920 window.console && console.error && console.error(err);
17921 };
17922
17923 this.$normalizePath = function(path) {
17924 return net.qualifyURL(path);
17925 };
17926
17927 this.terminate = function() {
17928 this._signal("terminate", {});
17929 this.deltaQueue = null;
17930 this.$worker.terminate();
17931 this.$worker = null;
17932 if (this.$doc)
17933 this.$doc.off("change", this.changeListener);
17934 this.$doc = null;
17935 };
17936
17937 this.send = function(cmd, args) {
17938 this.$worker.postMessage({command: cmd, args: args});
17939 };
17940
17941 this.call = function(cmd, args, callback) {
17942 if (callback) {
17943 var id = this.callbackId++;
17944 this.callbacks[id] = callback;
17945 args.push(id);
17946 }
17947 this.send(cmd, args);
17948 };
17949
17950 this.emit = function(event, data) {
17951 try {
17952 this.$worker.postMessage({event: event, data: {data: data.data}});
17953 }
17954 catch(ex) {
17955 console.error(ex.stack);
17956 }
17957 };
17958
17959 this.attachToDocument = function(doc) {
17960 if (this.$doc)
17961 this.terminate();
17962
17963 this.$doc = doc;
17964 this.call("setValue", [doc.getValue()]);
17965 doc.on("change", this.changeListener);
17966 };
17967
17968 this.changeListener = function(delta) {
17969 if (!this.deltaQueue) {
17970 this.deltaQueue = [];
17971 setTimeout(this.$sendDeltaQueue, 0);
17972 }
17973 if (delta.action == "insert")
17974 this.deltaQueue.push(delta.start, delta.lines);
17975 else
17976 this.deltaQueue.push(delta.start, delta.end);
17977 };
17978
17979 this.$sendDeltaQueue = function() {
17980 var q = this.deltaQueue;
17981 if (!q) return;
17982 this.deltaQueue = null;
17983 if (q.length > 50 && q.length > this.$doc.getLength() >> 1) {
17984 this.call("setValue", [this.$doc.getValue()]);
17985 } else
17986 this.emit("change", {data: q});
17987 };
17988
17989}).call(WorkerClient.prototype);
17990
17991
17992var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
17993 this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
17994 this.changeListener = this.changeListener.bind(this);
17995 this.callbackId = 1;
17996 this.callbacks = {};
17997 this.messageBuffer = [];
17998
17999 var main = null;
18000 var emitSync = false;
18001 var sender = Object.create(EventEmitter);
18002 var _self = this;
18003
18004 this.$worker = {};
18005 this.$worker.terminate = function() {};
18006 this.$worker.postMessage = function(e) {
18007 _self.messageBuffer.push(e);
18008 if (main) {
18009 if (emitSync)
18010 setTimeout(processNext);
18011 else
18012 processNext();
18013 }
18014 };
18015 this.setEmitSync = function(val) { emitSync = val; };
18016
18017 var processNext = function() {
18018 var msg = _self.messageBuffer.shift();
18019 if (msg.command)
18020 main[msg.command].apply(main, msg.args);
18021 else if (msg.event)
18022 sender._signal(msg.event, msg.data);
18023 };
18024
18025 sender.postMessage = function(msg) {
18026 _self.onMessage({data: msg});
18027 };
18028 sender.callback = function(data, callbackId) {
18029 this.postMessage({type: "call", id: callbackId, data: data});
18030 };
18031 sender.emit = function(name, data) {
18032 this.postMessage({type: "event", name: name, data: data});
18033 };
18034
18035 config.loadModule(["worker", mod], function(Main) {
18036 main = new Main[classname](sender);
18037 while (_self.messageBuffer.length)
18038 processNext();
18039 });
18040};
18041
18042UIWorkerClient.prototype = WorkerClient.prototype;
18043
18044exports.UIWorkerClient = UIWorkerClient;
18045exports.WorkerClient = WorkerClient;
18046exports.createWorker = createWorker;
18047
18048
18049});
18050
18051ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"], function(acequire, exports, module) {
18052
18053var Range = acequire("./range").Range;
18054var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
18055var oop = acequire("./lib/oop");
18056
18057var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
18058 var _self = this;
18059 this.length = length;
18060 this.session = session;
18061 this.doc = session.getDocument();
18062 this.mainClass = mainClass;
18063 this.othersClass = othersClass;
18064 this.$onUpdate = this.onUpdate.bind(this);
18065 this.doc.on("change", this.$onUpdate);
18066 this.$others = others;
18067
18068 this.$onCursorChange = function() {
18069 setTimeout(function() {
18070 _self.onCursorChange();
18071 });
18072 };
18073
18074 this.$pos = pos;
18075 var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
18076 this.$undoStackDepth = undoStack.length;
18077 this.setup();
18078
18079 session.selection.on("changeCursor", this.$onCursorChange);
18080};
18081
18082(function() {
18083
18084 oop.implement(this, EventEmitter);
18085 this.setup = function() {
18086 var _self = this;
18087 var doc = this.doc;
18088 var session = this.session;
18089
18090 this.selectionBefore = session.selection.toJSON();
18091 if (session.selection.inMultiSelectMode)
18092 session.selection.toSingleRange();
18093
18094 this.pos = doc.createAnchor(this.$pos.row, this.$pos.column);
18095 var pos = this.pos;
18096 pos.$insertRight = true;
18097 pos.detach();
18098 pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
18099 this.others = [];
18100 this.$others.forEach(function(other) {
18101 var anchor = doc.createAnchor(other.row, other.column);
18102 anchor.$insertRight = true;
18103 anchor.detach();
18104 _self.others.push(anchor);
18105 });
18106 session.setUndoSelect(false);
18107 };
18108 this.showOtherMarkers = function() {
18109 if (this.othersActive) return;
18110 var session = this.session;
18111 var _self = this;
18112 this.othersActive = true;
18113 this.others.forEach(function(anchor) {
18114 anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
18115 });
18116 };
18117 this.hideOtherMarkers = function() {
18118 if (!this.othersActive) return;
18119 this.othersActive = false;
18120 for (var i = 0; i < this.others.length; i++) {
18121 this.session.removeMarker(this.others[i].markerId);
18122 }
18123 };
18124 this.onUpdate = function(delta) {
18125 if (this.$updating)
18126 return this.updateAnchors(delta);
18127
18128 var range = delta;
18129 if (range.start.row !== range.end.row) return;
18130 if (range.start.row !== this.pos.row) return;
18131 this.$updating = true;
18132 var lengthDiff = delta.action === "insert" ? range.end.column - range.start.column : range.start.column - range.end.column;
18133 var inMainRange = range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1;
18134 var distanceFromStart = range.start.column - this.pos.column;
18135
18136 this.updateAnchors(delta);
18137
18138 if (inMainRange)
18139 this.length += lengthDiff;
18140
18141 if (inMainRange && !this.session.$fromUndo) {
18142 if (delta.action === 'insert') {
18143 for (var i = this.others.length - 1; i >= 0; i--) {
18144 var otherPos = this.others[i];
18145 var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
18146 this.doc.insertMergedLines(newPos, delta.lines);
18147 }
18148 } else if (delta.action === 'remove') {
18149 for (var i = this.others.length - 1; i >= 0; i--) {
18150 var otherPos = this.others[i];
18151 var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
18152 this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
18153 }
18154 }
18155 }
18156
18157 this.$updating = false;
18158 this.updateMarkers();
18159 };
18160
18161 this.updateAnchors = function(delta) {
18162 this.pos.onChange(delta);
18163 for (var i = this.others.length; i--;)
18164 this.others[i].onChange(delta);
18165 this.updateMarkers();
18166 };
18167
18168 this.updateMarkers = function() {
18169 if (this.$updating)
18170 return;
18171 var _self = this;
18172 var session = this.session;
18173 var updateMarker = function(pos, className) {
18174 session.removeMarker(pos.markerId);
18175 pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column+_self.length), className, null, false);
18176 };
18177 updateMarker(this.pos, this.mainClass);
18178 for (var i = this.others.length; i--;)
18179 updateMarker(this.others[i], this.othersClass);
18180 };
18181
18182 this.onCursorChange = function(event) {
18183 if (this.$updating || !this.session) return;
18184 var pos = this.session.selection.getCursor();
18185 if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
18186 this.showOtherMarkers();
18187 this._emit("cursorEnter", event);
18188 } else {
18189 this.hideOtherMarkers();
18190 this._emit("cursorLeave", event);
18191 }
18192 };
18193 this.detach = function() {
18194 this.session.removeMarker(this.pos && this.pos.markerId);
18195 this.hideOtherMarkers();
18196 this.doc.removeEventListener("change", this.$onUpdate);
18197 this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
18198 this.session.setUndoSelect(true);
18199 this.session = null;
18200 };
18201 this.cancel = function() {
18202 if (this.$undoStackDepth === -1)
18203 return;
18204 var undoManager = this.session.getUndoManager();
18205 var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
18206 for (var i = 0; i < undosRequired; i++) {
18207 undoManager.undo(true);
18208 }
18209 if (this.selectionBefore)
18210 this.session.selection.fromJSON(this.selectionBefore);
18211 };
18212}).call(PlaceHolder.prototype);
18213
18214
18215exports.PlaceHolder = PlaceHolder;
18216});
18217
18218ace.define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
18219
18220var event = acequire("../lib/event");
18221var useragent = acequire("../lib/useragent");
18222function isSamePoint(p1, p2) {
18223 return p1.row == p2.row && p1.column == p2.column;
18224}
18225
18226function onMouseDown(e) {
18227 var ev = e.domEvent;
18228 var alt = ev.altKey;
18229 var shift = ev.shiftKey;
18230 var ctrl = ev.ctrlKey;
18231 var accel = e.getAccelKey();
18232 var button = e.getButton();
18233
18234 if (ctrl && useragent.isMac)
18235 button = ev.button;
18236
18237 if (e.editor.inMultiSelectMode && button == 2) {
18238 e.editor.textInput.onContextMenu(e.domEvent);
18239 return;
18240 }
18241
18242 if (!ctrl && !alt && !accel) {
18243 if (button === 0 && e.editor.inMultiSelectMode)
18244 e.editor.exitMultiSelectMode();
18245 return;
18246 }
18247
18248 if (button !== 0)
18249 return;
18250
18251 var editor = e.editor;
18252 var selection = editor.selection;
18253 var isMultiSelect = editor.inMultiSelectMode;
18254 var pos = e.getDocumentPosition();
18255 var cursor = selection.getCursor();
18256 var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
18257
18258 var mouseX = e.x, mouseY = e.y;
18259 var onMouseSelection = function(e) {
18260 mouseX = e.clientX;
18261 mouseY = e.clientY;
18262 };
18263
18264 var session = editor.session;
18265 var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
18266 var screenCursor = screenAnchor;
18267
18268 var selectionMode;
18269 if (editor.$mouseHandler.$enableJumpToDef) {
18270 if (ctrl && alt || accel && alt)
18271 selectionMode = shift ? "block" : "add";
18272 else if (alt && editor.$blockSelectEnabled)
18273 selectionMode = "block";
18274 } else {
18275 if (accel && !alt) {
18276 selectionMode = "add";
18277 if (!isMultiSelect && shift)
18278 return;
18279 } else if (alt && editor.$blockSelectEnabled) {
18280 selectionMode = "block";
18281 }
18282 }
18283
18284 if (selectionMode && useragent.isMac && ev.ctrlKey) {
18285 editor.$mouseHandler.cancelContextMenu();
18286 }
18287
18288 if (selectionMode == "add") {
18289 if (!isMultiSelect && inSelection)
18290 return; // dragging
18291
18292 if (!isMultiSelect) {
18293 var range = selection.toOrientedRange();
18294 editor.addSelectionMarker(range);
18295 }
18296
18297 var oldRange = selection.rangeList.rangeAtPoint(pos);
18298
18299
18300 editor.$blockScrolling++;
18301 editor.inVirtualSelectionMode = true;
18302
18303 if (shift) {
18304 oldRange = null;
18305 range = selection.ranges[0] || range;
18306 editor.removeSelectionMarker(range);
18307 }
18308 editor.once("mouseup", function() {
18309 var tmpSel = selection.toOrientedRange();
18310
18311 if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
18312 selection.substractPoint(tmpSel.cursor);
18313 else {
18314 if (shift) {
18315 selection.substractPoint(range.cursor);
18316 } else if (range) {
18317 editor.removeSelectionMarker(range);
18318 selection.addRange(range);
18319 }
18320 selection.addRange(tmpSel);
18321 }
18322 editor.$blockScrolling--;
18323 editor.inVirtualSelectionMode = false;
18324 });
18325
18326 } else if (selectionMode == "block") {
18327 e.stop();
18328 editor.inVirtualSelectionMode = true;
18329 var initialRange;
18330 var rectSel = [];
18331 var blockSelect = function() {
18332 var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
18333 var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX);
18334
18335 if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))
18336 return;
18337 screenCursor = newCursor;
18338
18339 editor.$blockScrolling++;
18340 editor.selection.moveToPosition(cursor);
18341 editor.renderer.scrollCursorIntoView();
18342
18343 editor.removeSelectionMarkers(rectSel);
18344 rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
18345 if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())
18346 rectSel[0] = editor.$mouseHandler.$clickSelection.clone();
18347 rectSel.forEach(editor.addSelectionMarker, editor);
18348 editor.updateSelectionMarkers();
18349 editor.$blockScrolling--;
18350 };
18351 editor.$blockScrolling++;
18352 if (isMultiSelect && !accel) {
18353 selection.toSingleRange();
18354 } else if (!isMultiSelect && accel) {
18355 initialRange = selection.toOrientedRange();
18356 editor.addSelectionMarker(initialRange);
18357 }
18358
18359 if (shift)
18360 screenAnchor = session.documentToScreenPosition(selection.lead);
18361 else
18362 selection.moveToPosition(pos);
18363 editor.$blockScrolling--;
18364
18365 screenCursor = {row: -1, column: -1};
18366
18367 var onMouseSelectionEnd = function(e) {
18368 clearInterval(timerId);
18369 editor.removeSelectionMarkers(rectSel);
18370 if (!rectSel.length)
18371 rectSel = [selection.toOrientedRange()];
18372 editor.$blockScrolling++;
18373 if (initialRange) {
18374 editor.removeSelectionMarker(initialRange);
18375 selection.toSingleRange(initialRange);
18376 }
18377 for (var i = 0; i < rectSel.length; i++)
18378 selection.addRange(rectSel[i]);
18379 editor.inVirtualSelectionMode = false;
18380 editor.$mouseHandler.$clickSelection = null;
18381 editor.$blockScrolling--;
18382 };
18383
18384 var onSelectionInterval = blockSelect;
18385
18386 event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
18387 var timerId = setInterval(function() {onSelectionInterval();}, 20);
18388
18389 return e.preventDefault();
18390 }
18391}
18392
18393
18394exports.onMouseDown = onMouseDown;
18395
18396});
18397
18398ace.define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"], function(acequire, exports, module) {
18399exports.defaultCommands = [{
18400 name: "addCursorAbove",
18401 exec: function(editor) { editor.selectMoreLines(-1); },
18402 bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
18403 scrollIntoView: "cursor",
18404 readOnly: true
18405}, {
18406 name: "addCursorBelow",
18407 exec: function(editor) { editor.selectMoreLines(1); },
18408 bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
18409 scrollIntoView: "cursor",
18410 readOnly: true
18411}, {
18412 name: "addCursorAboveSkipCurrent",
18413 exec: function(editor) { editor.selectMoreLines(-1, true); },
18414 bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
18415 scrollIntoView: "cursor",
18416 readOnly: true
18417}, {
18418 name: "addCursorBelowSkipCurrent",
18419 exec: function(editor) { editor.selectMoreLines(1, true); },
18420 bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
18421 scrollIntoView: "cursor",
18422 readOnly: true
18423}, {
18424 name: "selectMoreBefore",
18425 exec: function(editor) { editor.selectMore(-1); },
18426 bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
18427 scrollIntoView: "cursor",
18428 readOnly: true
18429}, {
18430 name: "selectMoreAfter",
18431 exec: function(editor) { editor.selectMore(1); },
18432 bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
18433 scrollIntoView: "cursor",
18434 readOnly: true
18435}, {
18436 name: "selectNextBefore",
18437 exec: function(editor) { editor.selectMore(-1, true); },
18438 bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
18439 scrollIntoView: "cursor",
18440 readOnly: true
18441}, {
18442 name: "selectNextAfter",
18443 exec: function(editor) { editor.selectMore(1, true); },
18444 bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
18445 scrollIntoView: "cursor",
18446 readOnly: true
18447}, {
18448 name: "splitIntoLines",
18449 exec: function(editor) { editor.multiSelect.splitIntoLines(); },
18450 bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
18451 readOnly: true
18452}, {
18453 name: "alignCursors",
18454 exec: function(editor) { editor.alignCursors(); },
18455 bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"},
18456 scrollIntoView: "cursor"
18457}, {
18458 name: "findAll",
18459 exec: function(editor) { editor.findAll(); },
18460 bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"},
18461 scrollIntoView: "cursor",
18462 readOnly: true
18463}];
18464exports.multiSelectCommands = [{
18465 name: "singleSelection",
18466 bindKey: "esc",
18467 exec: function(editor) { editor.exitMultiSelectMode(); },
18468 scrollIntoView: "cursor",
18469 readOnly: true,
18470 isAvailable: function(editor) {return editor && editor.inMultiSelectMode;}
18471}];
18472
18473var HashHandler = acequire("../keyboard/hash_handler").HashHandler;
18474exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
18475
18476});
18477
18478ace.define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"], function(acequire, exports, module) {
18479
18480var RangeList = acequire("./range_list").RangeList;
18481var Range = acequire("./range").Range;
18482var Selection = acequire("./selection").Selection;
18483var onMouseDown = acequire("./mouse/multi_select_handler").onMouseDown;
18484var event = acequire("./lib/event");
18485var lang = acequire("./lib/lang");
18486var commands = acequire("./commands/multi_select_commands");
18487exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
18488var Search = acequire("./search").Search;
18489var search = new Search();
18490
18491function find(session, needle, dir) {
18492 search.$options.wrap = true;
18493 search.$options.needle = needle;
18494 search.$options.backwards = dir == -1;
18495 return search.find(session);
18496}
18497var EditSession = acequire("./edit_session").EditSession;
18498(function() {
18499 this.getSelectionMarkers = function() {
18500 return this.$selectionMarkers;
18501 };
18502}).call(EditSession.prototype);
18503(function() {
18504 this.ranges = null;
18505 this.rangeList = null;
18506 this.addRange = function(range, $blockChangeEvents) {
18507 if (!range)
18508 return;
18509
18510 if (!this.inMultiSelectMode && this.rangeCount === 0) {
18511 var oldRange = this.toOrientedRange();
18512 this.rangeList.add(oldRange);
18513 this.rangeList.add(range);
18514 if (this.rangeList.ranges.length != 2) {
18515 this.rangeList.removeAll();
18516 return $blockChangeEvents || this.fromOrientedRange(range);
18517 }
18518 this.rangeList.removeAll();
18519 this.rangeList.add(oldRange);
18520 this.$onAddRange(oldRange);
18521 }
18522
18523 if (!range.cursor)
18524 range.cursor = range.end;
18525
18526 var removed = this.rangeList.add(range);
18527
18528 this.$onAddRange(range);
18529
18530 if (removed.length)
18531 this.$onRemoveRange(removed);
18532
18533 if (this.rangeCount > 1 && !this.inMultiSelectMode) {
18534 this._signal("multiSelect");
18535 this.inMultiSelectMode = true;
18536 this.session.$undoSelect = false;
18537 this.rangeList.attach(this.session);
18538 }
18539
18540 return $blockChangeEvents || this.fromOrientedRange(range);
18541 };
18542
18543 this.toSingleRange = function(range) {
18544 range = range || this.ranges[0];
18545 var removed = this.rangeList.removeAll();
18546 if (removed.length)
18547 this.$onRemoveRange(removed);
18548
18549 range && this.fromOrientedRange(range);
18550 };
18551 this.substractPoint = function(pos) {
18552 var removed = this.rangeList.substractPoint(pos);
18553 if (removed) {
18554 this.$onRemoveRange(removed);
18555 return removed[0];
18556 }
18557 };
18558 this.mergeOverlappingRanges = function() {
18559 var removed = this.rangeList.merge();
18560 if (removed.length)
18561 this.$onRemoveRange(removed);
18562 else if(this.ranges[0])
18563 this.fromOrientedRange(this.ranges[0]);
18564 };
18565
18566 this.$onAddRange = function(range) {
18567 this.rangeCount = this.rangeList.ranges.length;
18568 this.ranges.unshift(range);
18569 this._signal("addRange", {range: range});
18570 };
18571
18572 this.$onRemoveRange = function(removed) {
18573 this.rangeCount = this.rangeList.ranges.length;
18574 if (this.rangeCount == 1 && this.inMultiSelectMode) {
18575 var lastRange = this.rangeList.ranges.pop();
18576 removed.push(lastRange);
18577 this.rangeCount = 0;
18578 }
18579
18580 for (var i = removed.length; i--; ) {
18581 var index = this.ranges.indexOf(removed[i]);
18582 this.ranges.splice(index, 1);
18583 }
18584
18585 this._signal("removeRange", {ranges: removed});
18586
18587 if (this.rangeCount === 0 && this.inMultiSelectMode) {
18588 this.inMultiSelectMode = false;
18589 this._signal("singleSelect");
18590 this.session.$undoSelect = true;
18591 this.rangeList.detach(this.session);
18592 }
18593
18594 lastRange = lastRange || this.ranges[0];
18595 if (lastRange && !lastRange.isEqual(this.getRange()))
18596 this.fromOrientedRange(lastRange);
18597 };
18598 this.$initRangeList = function() {
18599 if (this.rangeList)
18600 return;
18601
18602 this.rangeList = new RangeList();
18603 this.ranges = [];
18604 this.rangeCount = 0;
18605 };
18606 this.getAllRanges = function() {
18607 return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];
18608 };
18609
18610 this.splitIntoLines = function () {
18611 if (this.rangeCount > 1) {
18612 var ranges = this.rangeList.ranges;
18613 var lastRange = ranges[ranges.length - 1];
18614 var range = Range.fromPoints(ranges[0].start, lastRange.end);
18615
18616 this.toSingleRange();
18617 this.setSelectionRange(range, lastRange.cursor == lastRange.start);
18618 } else {
18619 var range = this.getRange();
18620 var isBackwards = this.isBackwards();
18621 var startRow = range.start.row;
18622 var endRow = range.end.row;
18623 if (startRow == endRow) {
18624 if (isBackwards)
18625 var start = range.end, end = range.start;
18626 else
18627 var start = range.start, end = range.end;
18628
18629 this.addRange(Range.fromPoints(end, end));
18630 this.addRange(Range.fromPoints(start, start));
18631 return;
18632 }
18633
18634 var rectSel = [];
18635 var r = this.getLineRange(startRow, true);
18636 r.start.column = range.start.column;
18637 rectSel.push(r);
18638
18639 for (var i = startRow + 1; i < endRow; i++)
18640 rectSel.push(this.getLineRange(i, true));
18641
18642 r = this.getLineRange(endRow, true);
18643 r.end.column = range.end.column;
18644 rectSel.push(r);
18645
18646 rectSel.forEach(this.addRange, this);
18647 }
18648 };
18649 this.toggleBlockSelection = function () {
18650 if (this.rangeCount > 1) {
18651 var ranges = this.rangeList.ranges;
18652 var lastRange = ranges[ranges.length - 1];
18653 var range = Range.fromPoints(ranges[0].start, lastRange.end);
18654
18655 this.toSingleRange();
18656 this.setSelectionRange(range, lastRange.cursor == lastRange.start);
18657 } else {
18658 var cursor = this.session.documentToScreenPosition(this.selectionLead);
18659 var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
18660
18661 var rectSel = this.rectangularRangeBlock(cursor, anchor);
18662 rectSel.forEach(this.addRange, this);
18663 }
18664 };
18665 this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
18666 var rectSel = [];
18667
18668 var xBackwards = screenCursor.column < screenAnchor.column;
18669 if (xBackwards) {
18670 var startColumn = screenCursor.column;
18671 var endColumn = screenAnchor.column;
18672 var startOffsetX = screenCursor.offsetX;
18673 var endOffsetX = screenAnchor.offsetX;
18674 } else {
18675 var startColumn = screenAnchor.column;
18676 var endColumn = screenCursor.column;
18677 var startOffsetX = screenAnchor.offsetX;
18678 var endOffsetX = screenCursor.offsetX;
18679 }
18680
18681 var yBackwards = screenCursor.row < screenAnchor.row;
18682 if (yBackwards) {
18683 var startRow = screenCursor.row;
18684 var endRow = screenAnchor.row;
18685 } else {
18686 var startRow = screenAnchor.row;
18687 var endRow = screenCursor.row;
18688 }
18689
18690 if (startColumn < 0)
18691 startColumn = 0;
18692 if (startRow < 0)
18693 startRow = 0;
18694
18695 if (startRow == endRow)
18696 includeEmptyLines = true;
18697
18698 for (var row = startRow; row <= endRow; row++) {
18699 var range = Range.fromPoints(
18700 this.session.screenToDocumentPosition(row, startColumn, startOffsetX),
18701 this.session.screenToDocumentPosition(row, endColumn, endOffsetX)
18702 );
18703 if (range.isEmpty()) {
18704 if (docEnd && isSamePoint(range.end, docEnd))
18705 break;
18706 var docEnd = range.end;
18707 }
18708 range.cursor = xBackwards ? range.start : range.end;
18709 rectSel.push(range);
18710 }
18711
18712 if (yBackwards)
18713 rectSel.reverse();
18714
18715 if (!includeEmptyLines) {
18716 var end = rectSel.length - 1;
18717 while (rectSel[end].isEmpty() && end > 0)
18718 end--;
18719 if (end > 0) {
18720 var start = 0;
18721 while (rectSel[start].isEmpty())
18722 start++;
18723 }
18724 for (var i = end; i >= start; i--) {
18725 if (rectSel[i].isEmpty())
18726 rectSel.splice(i, 1);
18727 }
18728 }
18729
18730 return rectSel;
18731 };
18732}).call(Selection.prototype);
18733var Editor = acequire("./editor").Editor;
18734(function() {
18735 this.updateSelectionMarkers = function() {
18736 this.renderer.updateCursor();
18737 this.renderer.updateBackMarkers();
18738 };
18739 this.addSelectionMarker = function(orientedRange) {
18740 if (!orientedRange.cursor)
18741 orientedRange.cursor = orientedRange.end;
18742
18743 var style = this.getSelectionStyle();
18744 orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
18745
18746 this.session.$selectionMarkers.push(orientedRange);
18747 this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
18748 return orientedRange;
18749 };
18750 this.removeSelectionMarker = function(range) {
18751 if (!range.marker)
18752 return;
18753 this.session.removeMarker(range.marker);
18754 var index = this.session.$selectionMarkers.indexOf(range);
18755 if (index != -1)
18756 this.session.$selectionMarkers.splice(index, 1);
18757 this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
18758 };
18759
18760 this.removeSelectionMarkers = function(ranges) {
18761 var markerList = this.session.$selectionMarkers;
18762 for (var i = ranges.length; i--; ) {
18763 var range = ranges[i];
18764 if (!range.marker)
18765 continue;
18766 this.session.removeMarker(range.marker);
18767 var index = markerList.indexOf(range);
18768 if (index != -1)
18769 markerList.splice(index, 1);
18770 }
18771 this.session.selectionMarkerCount = markerList.length;
18772 };
18773
18774 this.$onAddRange = function(e) {
18775 this.addSelectionMarker(e.range);
18776 this.renderer.updateCursor();
18777 this.renderer.updateBackMarkers();
18778 };
18779
18780 this.$onRemoveRange = function(e) {
18781 this.removeSelectionMarkers(e.ranges);
18782 this.renderer.updateCursor();
18783 this.renderer.updateBackMarkers();
18784 };
18785
18786 this.$onMultiSelect = function(e) {
18787 if (this.inMultiSelectMode)
18788 return;
18789 this.inMultiSelectMode = true;
18790
18791 this.setStyle("ace_multiselect");
18792 this.keyBinding.addKeyboardHandler(commands.keyboardHandler);
18793 this.commands.setDefaultHandler("exec", this.$onMultiSelectExec);
18794
18795 this.renderer.updateCursor();
18796 this.renderer.updateBackMarkers();
18797 };
18798
18799 this.$onSingleSelect = function(e) {
18800 if (this.session.multiSelect.inVirtualMode)
18801 return;
18802 this.inMultiSelectMode = false;
18803
18804 this.unsetStyle("ace_multiselect");
18805 this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);
18806
18807 this.commands.removeDefaultHandler("exec", this.$onMultiSelectExec);
18808 this.renderer.updateCursor();
18809 this.renderer.updateBackMarkers();
18810 this._emit("changeSelection");
18811 };
18812
18813 this.$onMultiSelectExec = function(e) {
18814 var command = e.command;
18815 var editor = e.editor;
18816 if (!editor.multiSelect)
18817 return;
18818 if (!command.multiSelectAction) {
18819 var result = command.exec(editor, e.args || {});
18820 editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
18821 editor.multiSelect.mergeOverlappingRanges();
18822 } else if (command.multiSelectAction == "forEach") {
18823 result = editor.forEachSelection(command, e.args);
18824 } else if (command.multiSelectAction == "forEachLine") {
18825 result = editor.forEachSelection(command, e.args, true);
18826 } else if (command.multiSelectAction == "single") {
18827 editor.exitMultiSelectMode();
18828 result = command.exec(editor, e.args || {});
18829 } else {
18830 result = command.multiSelectAction(editor, e.args || {});
18831 }
18832 return result;
18833 };
18834 this.forEachSelection = function(cmd, args, options) {
18835 if (this.inVirtualSelectionMode)
18836 return;
18837 var keepOrder = options && options.keepOrder;
18838 var $byLines = options == true || options && options.$byLines;
18839 var session = this.session;
18840 var selection = this.selection;
18841 var rangeList = selection.rangeList;
18842 var ranges = (keepOrder ? selection : rangeList).ranges;
18843 var result;
18844
18845 if (!ranges.length)
18846 return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
18847
18848 var reg = selection._eventRegistry;
18849 selection._eventRegistry = {};
18850
18851 var tmpSel = new Selection(session);
18852 this.inVirtualSelectionMode = true;
18853 for (var i = ranges.length; i--;) {
18854 if ($byLines) {
18855 while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row)
18856 i--;
18857 }
18858 tmpSel.fromOrientedRange(ranges[i]);
18859 tmpSel.index = i;
18860 this.selection = session.selection = tmpSel;
18861 var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
18862 if (!result && cmdResult !== undefined)
18863 result = cmdResult;
18864 tmpSel.toOrientedRange(ranges[i]);
18865 }
18866 tmpSel.detach();
18867
18868 this.selection = session.selection = selection;
18869 this.inVirtualSelectionMode = false;
18870 selection._eventRegistry = reg;
18871 selection.mergeOverlappingRanges();
18872
18873 var anim = this.renderer.$scrollAnimation;
18874 this.onCursorChange();
18875 this.onSelectionChange();
18876 if (anim && anim.from == anim.to)
18877 this.renderer.animateScrolling(anim.from);
18878
18879 return result;
18880 };
18881 this.exitMultiSelectMode = function() {
18882 if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
18883 return;
18884 this.multiSelect.toSingleRange();
18885 };
18886
18887 this.getSelectedText = function() {
18888 var text = "";
18889 if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
18890 var ranges = this.multiSelect.rangeList.ranges;
18891 var buf = [];
18892 for (var i = 0; i < ranges.length; i++) {
18893 buf.push(this.session.getTextRange(ranges[i]));
18894 }
18895 var nl = this.session.getDocument().getNewLineCharacter();
18896 text = buf.join(nl);
18897 if (text.length == (buf.length - 1) * nl.length)
18898 text = "";
18899 } else if (!this.selection.isEmpty()) {
18900 text = this.session.getTextRange(this.getSelectionRange());
18901 }
18902 return text;
18903 };
18904
18905 this.$checkMultiselectChange = function(e, anchor) {
18906 if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
18907 var range = this.multiSelect.ranges[0];
18908 if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)
18909 return;
18910 var pos = anchor == this.multiSelect.anchor
18911 ? range.cursor == range.start ? range.end : range.start
18912 : range.cursor;
18913 if (pos.row != anchor.row
18914 || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column)
18915 this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());
18916 }
18917 };
18918 this.findAll = function(needle, options, additive) {
18919 options = options || {};
18920 options.needle = needle || options.needle;
18921 if (options.needle == undefined) {
18922 var range = this.selection.isEmpty()
18923 ? this.selection.getWordRange()
18924 : this.selection.getRange();
18925 options.needle = this.session.getTextRange(range);
18926 }
18927 this.$search.set(options);
18928
18929 var ranges = this.$search.findAll(this.session);
18930 if (!ranges.length)
18931 return 0;
18932
18933 this.$blockScrolling += 1;
18934 var selection = this.multiSelect;
18935
18936 if (!additive)
18937 selection.toSingleRange(ranges[0]);
18938
18939 for (var i = ranges.length; i--; )
18940 selection.addRange(ranges[i], true);
18941 if (range && selection.rangeList.rangeAtPoint(range.start))
18942 selection.addRange(range, true);
18943
18944 this.$blockScrolling -= 1;
18945
18946 return ranges.length;
18947 };
18948 this.selectMoreLines = function(dir, skip) {
18949 var range = this.selection.toOrientedRange();
18950 var isBackwards = range.cursor == range.end;
18951
18952 var screenLead = this.session.documentToScreenPosition(range.cursor);
18953 if (this.selection.$desiredColumn)
18954 screenLead.column = this.selection.$desiredColumn;
18955
18956 var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
18957
18958 if (!range.isEmpty()) {
18959 var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
18960 var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
18961 } else {
18962 var anchor = lead;
18963 }
18964
18965 if (isBackwards) {
18966 var newRange = Range.fromPoints(lead, anchor);
18967 newRange.cursor = newRange.start;
18968 } else {
18969 var newRange = Range.fromPoints(anchor, lead);
18970 newRange.cursor = newRange.end;
18971 }
18972
18973 newRange.desiredColumn = screenLead.column;
18974 if (!this.selection.inMultiSelectMode) {
18975 this.selection.addRange(range);
18976 } else {
18977 if (skip)
18978 var toRemove = range.cursor;
18979 }
18980
18981 this.selection.addRange(newRange);
18982 if (toRemove)
18983 this.selection.substractPoint(toRemove);
18984 };
18985 this.transposeSelections = function(dir) {
18986 var session = this.session;
18987 var sel = session.multiSelect;
18988 var all = sel.ranges;
18989
18990 for (var i = all.length; i--; ) {
18991 var range = all[i];
18992 if (range.isEmpty()) {
18993 var tmp = session.getWordRange(range.start.row, range.start.column);
18994 range.start.row = tmp.start.row;
18995 range.start.column = tmp.start.column;
18996 range.end.row = tmp.end.row;
18997 range.end.column = tmp.end.column;
18998 }
18999 }
19000 sel.mergeOverlappingRanges();
19001
19002 var words = [];
19003 for (var i = all.length; i--; ) {
19004 var range = all[i];
19005 words.unshift(session.getTextRange(range));
19006 }
19007
19008 if (dir < 0)
19009 words.unshift(words.pop());
19010 else
19011 words.push(words.shift());
19012
19013 for (var i = all.length; i--; ) {
19014 var range = all[i];
19015 var tmp = range.clone();
19016 session.replace(range, words[i]);
19017 range.start.row = tmp.start.row;
19018 range.start.column = tmp.start.column;
19019 }
19020 };
19021 this.selectMore = function(dir, skip, stopAtFirst) {
19022 var session = this.session;
19023 var sel = session.multiSelect;
19024
19025 var range = sel.toOrientedRange();
19026 if (range.isEmpty()) {
19027 range = session.getWordRange(range.start.row, range.start.column);
19028 range.cursor = dir == -1 ? range.start : range.end;
19029 this.multiSelect.addRange(range);
19030 if (stopAtFirst)
19031 return;
19032 }
19033 var needle = session.getTextRange(range);
19034
19035 var newRange = find(session, needle, dir);
19036 if (newRange) {
19037 newRange.cursor = dir == -1 ? newRange.start : newRange.end;
19038 this.$blockScrolling += 1;
19039 this.session.unfold(newRange);
19040 this.multiSelect.addRange(newRange);
19041 this.$blockScrolling -= 1;
19042 this.renderer.scrollCursorIntoView(null, 0.5);
19043 }
19044 if (skip)
19045 this.multiSelect.substractPoint(range.cursor);
19046 };
19047 this.alignCursors = function() {
19048 var session = this.session;
19049 var sel = session.multiSelect;
19050 var ranges = sel.ranges;
19051 var row = -1;
19052 var sameRowRanges = ranges.filter(function(r) {
19053 if (r.cursor.row == row)
19054 return true;
19055 row = r.cursor.row;
19056 });
19057
19058 if (!ranges.length || sameRowRanges.length == ranges.length - 1) {
19059 var range = this.selection.getRange();
19060 var fr = range.start.row, lr = range.end.row;
19061 var guessRange = fr == lr;
19062 if (guessRange) {
19063 var max = this.session.getLength();
19064 var line;
19065 do {
19066 line = this.session.getLine(lr);
19067 } while (/[=:]/.test(line) && ++lr < max);
19068 do {
19069 line = this.session.getLine(fr);
19070 } while (/[=:]/.test(line) && --fr > 0);
19071
19072 if (fr < 0) fr = 0;
19073 if (lr >= max) lr = max - 1;
19074 }
19075 var lines = this.session.removeFullLines(fr, lr);
19076 lines = this.$reAlignText(lines, guessRange);
19077 this.session.insert({row: fr, column: 0}, lines.join("\n") + "\n");
19078 if (!guessRange) {
19079 range.start.column = 0;
19080 range.end.column = lines[lines.length - 1].length;
19081 }
19082 this.selection.setRange(range);
19083 } else {
19084 sameRowRanges.forEach(function(r) {
19085 sel.substractPoint(r.cursor);
19086 });
19087
19088 var maxCol = 0;
19089 var minSpace = Infinity;
19090 var spaceOffsets = ranges.map(function(r) {
19091 var p = r.cursor;
19092 var line = session.getLine(p.row);
19093 var spaceOffset = line.substr(p.column).search(/\S/g);
19094 if (spaceOffset == -1)
19095 spaceOffset = 0;
19096
19097 if (p.column > maxCol)
19098 maxCol = p.column;
19099 if (spaceOffset < minSpace)
19100 minSpace = spaceOffset;
19101 return spaceOffset;
19102 });
19103 ranges.forEach(function(r, i) {
19104 var p = r.cursor;
19105 var l = maxCol - p.column;
19106 var d = spaceOffsets[i] - minSpace;
19107 if (l > d)
19108 session.insert(p, lang.stringRepeat(" ", l - d));
19109 else
19110 session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
19111
19112 r.start.column = r.end.column = maxCol;
19113 r.start.row = r.end.row = p.row;
19114 r.cursor = r.end;
19115 });
19116 sel.fromOrientedRange(ranges[0]);
19117 this.renderer.updateCursor();
19118 this.renderer.updateBackMarkers();
19119 }
19120 };
19121
19122 this.$reAlignText = function(lines, forceLeft) {
19123 var isLeftAligned = true, isRightAligned = true;
19124 var startW, textW, endW;
19125
19126 return lines.map(function(line) {
19127 var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
19128 if (!m)
19129 return [line];
19130
19131 if (startW == null) {
19132 startW = m[1].length;
19133 textW = m[2].length;
19134 endW = m[3].length;
19135 return m;
19136 }
19137
19138 if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
19139 isRightAligned = false;
19140 if (startW != m[1].length)
19141 isLeftAligned = false;
19142
19143 if (startW > m[1].length)
19144 startW = m[1].length;
19145 if (textW < m[2].length)
19146 textW = m[2].length;
19147 if (endW > m[3].length)
19148 endW = m[3].length;
19149
19150 return m;
19151 }).map(forceLeft ? alignLeft :
19152 isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
19153
19154 function spaces(n) {
19155 return lang.stringRepeat(" ", n);
19156 }
19157
19158 function alignLeft(m) {
19159 return !m[2] ? m[0] : spaces(startW) + m[2]
19160 + spaces(textW - m[2].length + endW)
19161 + m[4].replace(/^([=:])\s+/, "$1 ");
19162 }
19163 function alignRight(m) {
19164 return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
19165 + spaces(endW)
19166 + m[4].replace(/^([=:])\s+/, "$1 ");
19167 }
19168 function unAlign(m) {
19169 return !m[2] ? m[0] : spaces(startW) + m[2]
19170 + spaces(endW)
19171 + m[4].replace(/^([=:])\s+/, "$1 ");
19172 }
19173 };
19174}).call(Editor.prototype);
19175
19176
19177function isSamePoint(p1, p2) {
19178 return p1.row == p2.row && p1.column == p2.column;
19179}
19180exports.onSessionChange = function(e) {
19181 var session = e.session;
19182 if (session && !session.multiSelect) {
19183 session.$selectionMarkers = [];
19184 session.selection.$initRangeList();
19185 session.multiSelect = session.selection;
19186 }
19187 this.multiSelect = session && session.multiSelect;
19188
19189 var oldSession = e.oldSession;
19190 if (oldSession) {
19191 oldSession.multiSelect.off("addRange", this.$onAddRange);
19192 oldSession.multiSelect.off("removeRange", this.$onRemoveRange);
19193 oldSession.multiSelect.off("multiSelect", this.$onMultiSelect);
19194 oldSession.multiSelect.off("singleSelect", this.$onSingleSelect);
19195 oldSession.multiSelect.lead.off("change", this.$checkMultiselectChange);
19196 oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange);
19197 }
19198
19199 if (session) {
19200 session.multiSelect.on("addRange", this.$onAddRange);
19201 session.multiSelect.on("removeRange", this.$onRemoveRange);
19202 session.multiSelect.on("multiSelect", this.$onMultiSelect);
19203 session.multiSelect.on("singleSelect", this.$onSingleSelect);
19204 session.multiSelect.lead.on("change", this.$checkMultiselectChange);
19205 session.multiSelect.anchor.on("change", this.$checkMultiselectChange);
19206 }
19207
19208 if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {
19209 if (session.selection.inMultiSelectMode)
19210 this.$onMultiSelect();
19211 else
19212 this.$onSingleSelect();
19213 }
19214};
19215function MultiSelect(editor) {
19216 if (editor.$multiselectOnSessionChange)
19217 return;
19218 editor.$onAddRange = editor.$onAddRange.bind(editor);
19219 editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
19220 editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
19221 editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
19222 editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);
19223 editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);
19224
19225 editor.$multiselectOnSessionChange(editor);
19226 editor.on("changeSession", editor.$multiselectOnSessionChange);
19227
19228 editor.on("mousedown", onMouseDown);
19229 editor.commands.addCommands(commands.defaultCommands);
19230
19231 addAltCursorListeners(editor);
19232}
19233
19234function addAltCursorListeners(editor){
19235 var el = editor.textInput.getElement();
19236 var altCursor = false;
19237 event.addListener(el, "keydown", function(e) {
19238 var altDown = e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey);
19239 if (editor.$blockSelectEnabled && altDown) {
19240 if (!altCursor) {
19241 editor.renderer.setMouseCursor("crosshair");
19242 altCursor = true;
19243 }
19244 } else if (altCursor) {
19245 reset();
19246 }
19247 });
19248
19249 event.addListener(el, "keyup", reset);
19250 event.addListener(el, "blur", reset);
19251 function reset(e) {
19252 if (altCursor) {
19253 editor.renderer.setMouseCursor("");
19254 altCursor = false;
19255 }
19256 }
19257}
19258
19259exports.MultiSelect = MultiSelect;
19260
19261
19262acequire("./config").defineOptions(Editor.prototype, "editor", {
19263 enableMultiselect: {
19264 set: function(val) {
19265 MultiSelect(this);
19266 if (val) {
19267 this.on("changeSession", this.$multiselectOnSessionChange);
19268 this.on("mousedown", onMouseDown);
19269 } else {
19270 this.off("changeSession", this.$multiselectOnSessionChange);
19271 this.off("mousedown", onMouseDown);
19272 }
19273 },
19274 value: true
19275 },
19276 enableBlockSelect: {
19277 set: function(val) {
19278 this.$blockSelectEnabled = val;
19279 },
19280 value: true
19281 }
19282});
19283
19284
19285
19286});
19287
19288ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"], function(acequire, exports, module) {
19289
19290var Range = acequire("../../range").Range;
19291
19292var FoldMode = exports.FoldMode = function() {};
19293
19294(function() {
19295
19296 this.foldingStartMarker = null;
19297 this.foldingStopMarker = null;
19298 this.getFoldWidget = function(session, foldStyle, row) {
19299 var line = session.getLine(row);
19300 if (this.foldingStartMarker.test(line))
19301 return "start";
19302 if (foldStyle == "markbeginend"
19303 && this.foldingStopMarker
19304 && this.foldingStopMarker.test(line))
19305 return "end";
19306 return "";
19307 };
19308
19309 this.getFoldWidgetRange = function(session, foldStyle, row) {
19310 return null;
19311 };
19312
19313 this.indentationBlock = function(session, row, column) {
19314 var re = /\S/;
19315 var line = session.getLine(row);
19316 var startLevel = line.search(re);
19317 if (startLevel == -1)
19318 return;
19319
19320 var startColumn = column || line.length;
19321 var maxRow = session.getLength();
19322 var startRow = row;
19323 var endRow = row;
19324
19325 while (++row < maxRow) {
19326 var level = session.getLine(row).search(re);
19327
19328 if (level == -1)
19329 continue;
19330
19331 if (level <= startLevel)
19332 break;
19333
19334 endRow = row;
19335 }
19336
19337 if (endRow > startRow) {
19338 var endColumn = session.getLine(endRow).length;
19339 return new Range(startRow, startColumn, endRow, endColumn);
19340 }
19341 };
19342
19343 this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
19344 var start = {row: row, column: column + 1};
19345 var end = session.$findClosingBracket(bracket, start, typeRe);
19346 if (!end)
19347 return;
19348
19349 var fw = session.foldWidgets[end.row];
19350 if (fw == null)
19351 fw = session.getFoldWidget(end.row);
19352
19353 if (fw == "start" && end.row > start.row) {
19354 end.row --;
19355 end.column = session.getLine(end.row).length;
19356 }
19357 return Range.fromPoints(start, end);
19358 };
19359
19360 this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
19361 var end = {row: row, column: column};
19362 var start = session.$findOpeningBracket(bracket, end);
19363
19364 if (!start)
19365 return;
19366
19367 start.column++;
19368 end.column--;
19369
19370 return Range.fromPoints(start, end);
19371 };
19372}).call(FoldMode.prototype);
19373
19374});
19375
19376ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) {
19377
19378exports.isDark = false;
19379exports.cssClass = "ace-tm";
19380exports.cssText = ".ace-tm .ace_gutter {\
19381background: #f0f0f0;\
19382color: #333;\
19383}\
19384.ace-tm .ace_print-margin {\
19385width: 1px;\
19386background: #e8e8e8;\
19387}\
19388.ace-tm .ace_fold {\
19389background-color: #6B72E6;\
19390}\
19391.ace-tm {\
19392background-color: #FFFFFF;\
19393color: black;\
19394}\
19395.ace-tm .ace_cursor {\
19396color: black;\
19397}\
19398.ace-tm .ace_invisible {\
19399color: rgb(191, 191, 191);\
19400}\
19401.ace-tm .ace_storage,\
19402.ace-tm .ace_keyword {\
19403color: blue;\
19404}\
19405.ace-tm .ace_constant {\
19406color: rgb(197, 6, 11);\
19407}\
19408.ace-tm .ace_constant.ace_buildin {\
19409color: rgb(88, 72, 246);\
19410}\
19411.ace-tm .ace_constant.ace_language {\
19412color: rgb(88, 92, 246);\
19413}\
19414.ace-tm .ace_constant.ace_library {\
19415color: rgb(6, 150, 14);\
19416}\
19417.ace-tm .ace_invalid {\
19418background-color: rgba(255, 0, 0, 0.1);\
19419color: red;\
19420}\
19421.ace-tm .ace_support.ace_function {\
19422color: rgb(60, 76, 114);\
19423}\
19424.ace-tm .ace_support.ace_constant {\
19425color: rgb(6, 150, 14);\
19426}\
19427.ace-tm .ace_support.ace_type,\
19428.ace-tm .ace_support.ace_class {\
19429color: rgb(109, 121, 222);\
19430}\
19431.ace-tm .ace_keyword.ace_operator {\
19432color: rgb(104, 118, 135);\
19433}\
19434.ace-tm .ace_string {\
19435color: rgb(3, 106, 7);\
19436}\
19437.ace-tm .ace_comment {\
19438color: rgb(76, 136, 107);\
19439}\
19440.ace-tm .ace_comment.ace_doc {\
19441color: rgb(0, 102, 255);\
19442}\
19443.ace-tm .ace_comment.ace_doc.ace_tag {\
19444color: rgb(128, 159, 191);\
19445}\
19446.ace-tm .ace_constant.ace_numeric {\
19447color: rgb(0, 0, 205);\
19448}\
19449.ace-tm .ace_variable {\
19450color: rgb(49, 132, 149);\
19451}\
19452.ace-tm .ace_xml-pe {\
19453color: rgb(104, 104, 91);\
19454}\
19455.ace-tm .ace_entity.ace_name.ace_function {\
19456color: #0000A2;\
19457}\
19458.ace-tm .ace_heading {\
19459color: rgb(12, 7, 255);\
19460}\
19461.ace-tm .ace_list {\
19462color:rgb(185, 6, 144);\
19463}\
19464.ace-tm .ace_meta.ace_tag {\
19465color:rgb(0, 22, 142);\
19466}\
19467.ace-tm .ace_string.ace_regex {\
19468color: rgb(255, 0, 0)\
19469}\
19470.ace-tm .ace_marker-layer .ace_selection {\
19471background: rgb(181, 213, 255);\
19472}\
19473.ace-tm.ace_multiselect .ace_selection.ace_start {\
19474box-shadow: 0 0 3px 0px white;\
19475}\
19476.ace-tm .ace_marker-layer .ace_step {\
19477background: rgb(252, 255, 0);\
19478}\
19479.ace-tm .ace_marker-layer .ace_stack {\
19480background: rgb(164, 229, 101);\
19481}\
19482.ace-tm .ace_marker-layer .ace_bracket {\
19483margin: -1px 0 0 -1px;\
19484border: 1px solid rgb(192, 192, 192);\
19485}\
19486.ace-tm .ace_marker-layer .ace_active-line {\
19487background: rgba(0, 0, 0, 0.07);\
19488}\
19489.ace-tm .ace_gutter-active-line {\
19490background-color : #dcdcdc;\
19491}\
19492.ace-tm .ace_marker-layer .ace_selected-word {\
19493background: rgb(250, 250, 255);\
19494border: 1px solid rgb(200, 200, 250);\
19495}\
19496.ace-tm .ace_indent-guide {\
19497background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
19498}\
19499";
19500
19501var dom = acequire("../lib/dom");
19502dom.importCssString(exports.cssText, exports.cssClass);
19503});
19504
19505ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(acequire, exports, module) {
19506
19507acequire("./lib/oop");
19508var dom = acequire("./lib/dom");
19509acequire("./range").Range;
19510
19511
19512function LineWidgets(session) {
19513 this.session = session;
19514 this.session.widgetManager = this;
19515 this.session.getRowLength = this.getRowLength;
19516 this.session.$getWidgetScreenLength = this.$getWidgetScreenLength;
19517 this.updateOnChange = this.updateOnChange.bind(this);
19518 this.renderWidgets = this.renderWidgets.bind(this);
19519 this.measureWidgets = this.measureWidgets.bind(this);
19520 this.session._changedWidgets = [];
19521 this.$onChangeEditor = this.$onChangeEditor.bind(this);
19522
19523 this.session.on("change", this.updateOnChange);
19524 this.session.on("changeFold", this.updateOnFold);
19525 this.session.on("changeEditor", this.$onChangeEditor);
19526}
19527
19528(function() {
19529 this.getRowLength = function(row) {
19530 var h;
19531 if (this.lineWidgets)
19532 h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
19533 else
19534 h = 0;
19535 if (!this.$useWrapMode || !this.$wrapData[row]) {
19536 return 1 + h;
19537 } else {
19538 return this.$wrapData[row].length + 1 + h;
19539 }
19540 };
19541
19542 this.$getWidgetScreenLength = function() {
19543 var screenRows = 0;
19544 this.lineWidgets.forEach(function(w){
19545 if (w && w.rowCount && !w.hidden)
19546 screenRows += w.rowCount;
19547 });
19548 return screenRows;
19549 };
19550
19551 this.$onChangeEditor = function(e) {
19552 this.attach(e.editor);
19553 };
19554
19555 this.attach = function(editor) {
19556 if (editor && editor.widgetManager && editor.widgetManager != this)
19557 editor.widgetManager.detach();
19558
19559 if (this.editor == editor)
19560 return;
19561
19562 this.detach();
19563 this.editor = editor;
19564
19565 if (editor) {
19566 editor.widgetManager = this;
19567 editor.renderer.on("beforeRender", this.measureWidgets);
19568 editor.renderer.on("afterRender", this.renderWidgets);
19569 }
19570 };
19571 this.detach = function(e) {
19572 var editor = this.editor;
19573 if (!editor)
19574 return;
19575
19576 this.editor = null;
19577 editor.widgetManager = null;
19578
19579 editor.renderer.off("beforeRender", this.measureWidgets);
19580 editor.renderer.off("afterRender", this.renderWidgets);
19581 var lineWidgets = this.session.lineWidgets;
19582 lineWidgets && lineWidgets.forEach(function(w) {
19583 if (w && w.el && w.el.parentNode) {
19584 w._inDocument = false;
19585 w.el.parentNode.removeChild(w.el);
19586 }
19587 });
19588 };
19589
19590 this.updateOnFold = function(e, session) {
19591 var lineWidgets = session.lineWidgets;
19592 if (!lineWidgets || !e.action)
19593 return;
19594 var fold = e.data;
19595 var start = fold.start.row;
19596 var end = fold.end.row;
19597 var hide = e.action == "add";
19598 for (var i = start + 1; i < end; i++) {
19599 if (lineWidgets[i])
19600 lineWidgets[i].hidden = hide;
19601 }
19602 if (lineWidgets[end]) {
19603 if (hide) {
19604 if (!lineWidgets[start])
19605 lineWidgets[start] = lineWidgets[end];
19606 else
19607 lineWidgets[end].hidden = hide;
19608 } else {
19609 if (lineWidgets[start] == lineWidgets[end])
19610 lineWidgets[start] = undefined;
19611 lineWidgets[end].hidden = hide;
19612 }
19613 }
19614 };
19615
19616 this.updateOnChange = function(delta) {
19617 var lineWidgets = this.session.lineWidgets;
19618 if (!lineWidgets) return;
19619
19620 var startRow = delta.start.row;
19621 var len = delta.end.row - startRow;
19622
19623 if (len === 0) ; else if (delta.action == 'remove') {
19624 var removed = lineWidgets.splice(startRow + 1, len);
19625 removed.forEach(function(w) {
19626 w && this.removeLineWidget(w);
19627 }, this);
19628 this.$updateRows();
19629 } else {
19630 var args = new Array(len);
19631 args.unshift(startRow, 0);
19632 lineWidgets.splice.apply(lineWidgets, args);
19633 this.$updateRows();
19634 }
19635 };
19636
19637 this.$updateRows = function() {
19638 var lineWidgets = this.session.lineWidgets;
19639 if (!lineWidgets) return;
19640 var noWidgets = true;
19641 lineWidgets.forEach(function(w, i) {
19642 if (w) {
19643 noWidgets = false;
19644 w.row = i;
19645 while (w.$oldWidget) {
19646 w.$oldWidget.row = i;
19647 w = w.$oldWidget;
19648 }
19649 }
19650 });
19651 if (noWidgets)
19652 this.session.lineWidgets = null;
19653 };
19654
19655 this.addLineWidget = function(w) {
19656 if (!this.session.lineWidgets)
19657 this.session.lineWidgets = new Array(this.session.getLength());
19658
19659 var old = this.session.lineWidgets[w.row];
19660 if (old) {
19661 w.$oldWidget = old;
19662 if (old.el && old.el.parentNode) {
19663 old.el.parentNode.removeChild(old.el);
19664 old._inDocument = false;
19665 }
19666 }
19667
19668 this.session.lineWidgets[w.row] = w;
19669
19670 w.session = this.session;
19671
19672 var renderer = this.editor.renderer;
19673 if (w.html && !w.el) {
19674 w.el = dom.createElement("div");
19675 w.el.innerHTML = w.html;
19676 }
19677 if (w.el) {
19678 dom.addCssClass(w.el, "ace_lineWidgetContainer");
19679 w.el.style.position = "absolute";
19680 w.el.style.zIndex = 5;
19681 renderer.container.appendChild(w.el);
19682 w._inDocument = true;
19683 }
19684
19685 if (!w.coverGutter) {
19686 w.el.style.zIndex = 3;
19687 }
19688 if (w.pixelHeight == null) {
19689 w.pixelHeight = w.el.offsetHeight;
19690 }
19691 if (w.rowCount == null) {
19692 w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
19693 }
19694
19695 var fold = this.session.getFoldAt(w.row, 0);
19696 w.$fold = fold;
19697 if (fold) {
19698 var lineWidgets = this.session.lineWidgets;
19699 if (w.row == fold.end.row && !lineWidgets[fold.start.row])
19700 lineWidgets[fold.start.row] = w;
19701 else
19702 w.hidden = true;
19703 }
19704
19705 this.session._emit("changeFold", {data:{start:{row: w.row}}});
19706
19707 this.$updateRows();
19708 this.renderWidgets(null, renderer);
19709 this.onWidgetChanged(w);
19710 return w;
19711 };
19712
19713 this.removeLineWidget = function(w) {
19714 w._inDocument = false;
19715 w.session = null;
19716 if (w.el && w.el.parentNode)
19717 w.el.parentNode.removeChild(w.el);
19718 if (w.editor && w.editor.destroy) try {
19719 w.editor.destroy();
19720 } catch(e){}
19721 if (this.session.lineWidgets) {
19722 var w1 = this.session.lineWidgets[w.row];
19723 if (w1 == w) {
19724 this.session.lineWidgets[w.row] = w.$oldWidget;
19725 if (w.$oldWidget)
19726 this.onWidgetChanged(w.$oldWidget);
19727 } else {
19728 while (w1) {
19729 if (w1.$oldWidget == w) {
19730 w1.$oldWidget = w.$oldWidget;
19731 break;
19732 }
19733 w1 = w1.$oldWidget;
19734 }
19735 }
19736 }
19737 this.session._emit("changeFold", {data:{start:{row: w.row}}});
19738 this.$updateRows();
19739 };
19740
19741 this.getWidgetsAtRow = function(row) {
19742 var lineWidgets = this.session.lineWidgets;
19743 var w = lineWidgets && lineWidgets[row];
19744 var list = [];
19745 while (w) {
19746 list.push(w);
19747 w = w.$oldWidget;
19748 }
19749 return list;
19750 };
19751
19752 this.onWidgetChanged = function(w) {
19753 this.session._changedWidgets.push(w);
19754 this.editor && this.editor.renderer.updateFull();
19755 };
19756
19757 this.measureWidgets = function(e, renderer) {
19758 var changedWidgets = this.session._changedWidgets;
19759 var config = renderer.layerConfig;
19760
19761 if (!changedWidgets || !changedWidgets.length) return;
19762 var min = Infinity;
19763 for (var i = 0; i < changedWidgets.length; i++) {
19764 var w = changedWidgets[i];
19765 if (!w || !w.el) continue;
19766 if (w.session != this.session) continue;
19767 if (!w._inDocument) {
19768 if (this.session.lineWidgets[w.row] != w)
19769 continue;
19770 w._inDocument = true;
19771 renderer.container.appendChild(w.el);
19772 }
19773
19774 w.h = w.el.offsetHeight;
19775
19776 if (!w.fixedWidth) {
19777 w.w = w.el.offsetWidth;
19778 w.screenWidth = Math.ceil(w.w / config.characterWidth);
19779 }
19780
19781 var rowCount = w.h / config.lineHeight;
19782 if (w.coverLine) {
19783 rowCount -= this.session.getRowLineCount(w.row);
19784 if (rowCount < 0)
19785 rowCount = 0;
19786 }
19787 if (w.rowCount != rowCount) {
19788 w.rowCount = rowCount;
19789 if (w.row < min)
19790 min = w.row;
19791 }
19792 }
19793 if (min != Infinity) {
19794 this.session._emit("changeFold", {data:{start:{row: min}}});
19795 this.session.lineWidgetWidth = null;
19796 }
19797 this.session._changedWidgets = [];
19798 };
19799
19800 this.renderWidgets = function(e, renderer) {
19801 var config = renderer.layerConfig;
19802 var lineWidgets = this.session.lineWidgets;
19803 if (!lineWidgets)
19804 return;
19805 var first = Math.min(this.firstRow, config.firstRow);
19806 var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);
19807
19808 while (first > 0 && !lineWidgets[first])
19809 first--;
19810
19811 this.firstRow = config.firstRow;
19812 this.lastRow = config.lastRow;
19813
19814 renderer.$cursorLayer.config = config;
19815 for (var i = first; i <= last; i++) {
19816 var w = lineWidgets[i];
19817 if (!w || !w.el) continue;
19818 if (w.hidden) {
19819 w.el.style.top = -100 - (w.pixelHeight || 0) + "px";
19820 continue;
19821 }
19822 if (!w._inDocument) {
19823 w._inDocument = true;
19824 renderer.container.appendChild(w.el);
19825 }
19826 var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top;
19827 if (!w.coverLine)
19828 top += config.lineHeight * this.session.getRowLineCount(w.row);
19829 w.el.style.top = top - config.offset + "px";
19830
19831 var left = w.coverGutter ? 0 : renderer.gutterWidth;
19832 if (!w.fixedWidth)
19833 left -= renderer.scrollLeft;
19834 w.el.style.left = left + "px";
19835
19836 if (w.fullWidth && w.screenWidth) {
19837 w.el.style.minWidth = config.width + 2 * config.padding + "px";
19838 }
19839
19840 if (w.fixedWidth) {
19841 w.el.style.right = renderer.scrollBar.getWidth() + "px";
19842 } else {
19843 w.el.style.right = "";
19844 }
19845 }
19846 };
19847
19848}).call(LineWidgets.prototype);
19849
19850
19851exports.LineWidgets = LineWidgets;
19852
19853});
19854
19855ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"], function(acequire, exports, module) {
19856var LineWidgets = acequire("../line_widgets").LineWidgets;
19857var dom = acequire("../lib/dom");
19858var Range = acequire("../range").Range;
19859
19860function binarySearch(array, needle, comparator) {
19861 var first = 0;
19862 var last = array.length - 1;
19863
19864 while (first <= last) {
19865 var mid = (first + last) >> 1;
19866 var c = comparator(needle, array[mid]);
19867 if (c > 0)
19868 first = mid + 1;
19869 else if (c < 0)
19870 last = mid - 1;
19871 else
19872 return mid;
19873 }
19874 return -(first + 1);
19875}
19876
19877function findAnnotations(session, row, dir) {
19878 var annotations = session.getAnnotations().sort(Range.comparePoints);
19879 if (!annotations.length)
19880 return;
19881
19882 var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints);
19883 if (i < 0)
19884 i = -i - 1;
19885
19886 if (i >= annotations.length)
19887 i = dir > 0 ? 0 : annotations.length - 1;
19888 else if (i === 0 && dir < 0)
19889 i = annotations.length - 1;
19890
19891 var annotation = annotations[i];
19892 if (!annotation || !dir)
19893 return;
19894
19895 if (annotation.row === row) {
19896 do {
19897 annotation = annotations[i += dir];
19898 } while (annotation && annotation.row === row);
19899 if (!annotation)
19900 return annotations.slice();
19901 }
19902
19903
19904 var matched = [];
19905 row = annotation.row;
19906 do {
19907 matched[dir < 0 ? "unshift" : "push"](annotation);
19908 annotation = annotations[i += dir];
19909 } while (annotation && annotation.row == row);
19910 return matched.length && matched;
19911}
19912
19913exports.showErrorMarker = function(editor, dir) {
19914 var session = editor.session;
19915 if (!session.widgetManager) {
19916 session.widgetManager = new LineWidgets(session);
19917 session.widgetManager.attach(editor);
19918 }
19919
19920 var pos = editor.getCursorPosition();
19921 var row = pos.row;
19922 var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) {
19923 return w.type == "errorMarker";
19924 })[0];
19925 if (oldWidget) {
19926 oldWidget.destroy();
19927 } else {
19928 row -= dir;
19929 }
19930 var annotations = findAnnotations(session, row, dir);
19931 var gutterAnno;
19932 if (annotations) {
19933 var annotation = annotations[0];
19934 pos.column = (annotation.pos && typeof annotation.column != "number"
19935 ? annotation.pos.sc
19936 : annotation.column) || 0;
19937 pos.row = annotation.row;
19938 gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row];
19939 } else if (oldWidget) {
19940 return;
19941 } else {
19942 gutterAnno = {
19943 text: ["Looks good!"],
19944 className: "ace_ok"
19945 };
19946 }
19947 editor.session.unfold(pos.row);
19948 editor.selection.moveToPosition(pos);
19949
19950 var w = {
19951 row: pos.row,
19952 fixedWidth: true,
19953 coverGutter: true,
19954 el: dom.createElement("div"),
19955 type: "errorMarker"
19956 };
19957 var el = w.el.appendChild(dom.createElement("div"));
19958 var arrow = w.el.appendChild(dom.createElement("div"));
19959 arrow.className = "error_widget_arrow " + gutterAnno.className;
19960
19961 var left = editor.renderer.$cursorLayer
19962 .getPixelPosition(pos).left;
19963 arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px";
19964
19965 w.el.className = "error_widget_wrapper";
19966 el.className = "error_widget " + gutterAnno.className;
19967 el.innerHTML = gutterAnno.text.join("<br>");
19968
19969 el.appendChild(dom.createElement("div"));
19970
19971 var kb = function(_, hashId, keyString) {
19972 if (hashId === 0 && (keyString === "esc" || keyString === "return")) {
19973 w.destroy();
19974 return {command: "null"};
19975 }
19976 };
19977
19978 w.destroy = function() {
19979 if (editor.$mouseHandler.isMousePressed)
19980 return;
19981 editor.keyBinding.removeKeyboardHandler(kb);
19982 session.widgetManager.removeLineWidget(w);
19983 editor.off("changeSelection", w.destroy);
19984 editor.off("changeSession", w.destroy);
19985 editor.off("mouseup", w.destroy);
19986 editor.off("change", w.destroy);
19987 };
19988
19989 editor.keyBinding.addKeyboardHandler(kb);
19990 editor.on("changeSelection", w.destroy);
19991 editor.on("changeSession", w.destroy);
19992 editor.on("mouseup", w.destroy);
19993 editor.on("change", w.destroy);
19994
19995 editor.session.widgetManager.addLineWidget(w);
19996
19997 w.el.onmousedown = editor.focus.bind(editor);
19998
19999 editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight});
20000};
20001
20002
20003dom.importCssString("\
20004 .error_widget_wrapper {\
20005 background: inherit;\
20006 color: inherit;\
20007 border:none\
20008 }\
20009 .error_widget {\
20010 border-top: solid 2px;\
20011 border-bottom: solid 2px;\
20012 margin: 5px 0;\
20013 padding: 10px 40px;\
20014 white-space: pre-wrap;\
20015 }\
20016 .error_widget.ace_error, .error_widget_arrow.ace_error{\
20017 border-color: #ff5a5a\
20018 }\
20019 .error_widget.ace_warning, .error_widget_arrow.ace_warning{\
20020 border-color: #F1D817\
20021 }\
20022 .error_widget.ace_info, .error_widget_arrow.ace_info{\
20023 border-color: #5a5a5a\
20024 }\
20025 .error_widget.ace_ok, .error_widget_arrow.ace_ok{\
20026 border-color: #5aaa5a\
20027 }\
20028 .error_widget_arrow {\
20029 position: absolute;\
20030 border: solid 5px;\
20031 border-top-color: transparent!important;\
20032 border-right-color: transparent!important;\
20033 border-left-color: transparent!important;\
20034 top: -5px;\
20035 }\
20036", "");
20037
20038});
20039
20040ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"], function(acequire, exports, module) {
20041
20042acequire("./lib/fixoldbrowsers");
20043
20044var dom = acequire("./lib/dom");
20045var event = acequire("./lib/event");
20046
20047var Editor = acequire("./editor").Editor;
20048var EditSession = acequire("./edit_session").EditSession;
20049var UndoManager = acequire("./undomanager").UndoManager;
20050var Renderer = acequire("./virtual_renderer").VirtualRenderer;
20051acequire("./worker/worker_client");
20052acequire("./keyboard/hash_handler");
20053acequire("./placeholder");
20054acequire("./multi_select");
20055acequire("./mode/folding/fold_mode");
20056acequire("./theme/textmate");
20057acequire("./ext/error_marker");
20058
20059exports.config = acequire("./config");
20060exports.acequire = acequire;
20061exports.edit = function(el) {
20062 if (typeof el == "string") {
20063 var _id = el;
20064 el = document.getElementById(_id);
20065 if (!el)
20066 throw new Error("ace.edit can't find div #" + _id);
20067 }
20068
20069 if (el && el.env && el.env.editor instanceof Editor)
20070 return el.env.editor;
20071
20072 var value = "";
20073 if (el && /input|textarea/i.test(el.tagName)) {
20074 var oldNode = el;
20075 value = oldNode.value;
20076 el = dom.createElement("pre");
20077 oldNode.parentNode.replaceChild(el, oldNode);
20078 } else if (el) {
20079 value = dom.getInnerText(el);
20080 el.innerHTML = "";
20081 }
20082
20083 var doc = exports.createEditSession(value);
20084
20085 var editor = new Editor(new Renderer(el));
20086 editor.setSession(doc);
20087
20088 var env = {
20089 document: doc,
20090 editor: editor,
20091 onResize: editor.resize.bind(editor, null)
20092 };
20093 if (oldNode) env.textarea = oldNode;
20094 event.addListener(window, "resize", env.onResize);
20095 editor.on("destroy", function() {
20096 event.removeListener(window, "resize", env.onResize);
20097 env.editor.container.env = null; // prevent memory leak on old ie
20098 });
20099 editor.container.env = editor.env = env;
20100 return editor;
20101};
20102exports.createEditSession = function(text, mode) {
20103 var doc = new EditSession(text, mode);
20104 doc.setUndoManager(new UndoManager());
20105 return doc;
20106};
20107exports.EditSession = EditSession;
20108exports.UndoManager = UndoManager;
20109exports.version = "1.2.9";
20110});
20111 (function() {
20112 ace.acequire(["ace/ace"], function(a) {
20113 if (a) {
20114 a.config.init(true);
20115 a.define = ace.define;
20116 }
20117 if (!window.ace)
20118 window.ace = a;
20119 for (var key in a) if (a.hasOwnProperty(key))
20120 window.ace[key] = a[key];
20121 });
20122 })();
20123
20124var brace = window.ace.acequire("ace/ace");
20125
20126var script = {
20127 name: 'FeiEditor',
20128 props: {
20129 modelValue: String,
20130 lang: {
20131 type: String,
20132 default: 'json'
20133 },
20134 theme: {
20135 type: String,
20136 default: 'chrome'
20137 },
20138 height: {
20139 type: String,
20140 default: '350'
20141 },
20142 width: {
20143 type: String,
20144 default: '100%'
20145 },
20146 fontSize: {
20147 type: Number,
20148 default: 12
20149 },
20150 options: Object,
20151 readonly: Boolean,
20152 wrap: {
20153 type: Boolean,
20154 default: false
20155 },
20156 snippets: {
20157 type: Boolean,
20158 default: true
20159 },
20160 styles: {
20161 type: Object
20162 }
20163 },
20164 data() {
20165 return {
20166 editor: null,
20167 contentBackup: ''
20168 };
20169 },
20170 emits: ['blur', 'init', 'update:modelValue', 'change'],
20171 computed: {
20172 wrapStyles() {
20173 return {
20174 width: this.width ? this.px(this.width) : '100%',
20175 height: this.height ? this.px(this.height) : '100%',
20176 border: '1px solid #e8e8e8',
20177 ...this.styles
20178 };
20179 }
20180 },
20181 methods: {
20182 px(n) {
20183 return /^\d*$/.test(n) ? `${n}px` : n;
20184 },
20185 getValue() {
20186 return this.editor.getValue();
20187 },
20188 handleBlur(event) {
20189 this.$emit('blur', event);
20190 }
20191 },
20192 watch: {
20193 modelValue(val) {
20194 if (this.contentBackup !== val) {
20195 this.editor.session.setValue(val, 1);
20196 this.contentBackup = val;
20197 }
20198 },
20199 theme(newTheme) {
20200 this.editor.setTheme('ace/theme/' + newTheme);
20201 },
20202 lang(newLang) {
20203 this.editor.getSession().setMode('ace/mode/' + newLang);
20204 },
20205 options(newOption) {
20206 this.editor.setOptions(newOption);
20207 },
20208 fontSize(newSize) {
20209 this.editor.setFontSize(newSize); // 设置文字大小
20210 },
20211
20212 readonly(val) {
20213 this.editor.setReadOnly(val); // 设置只读
20214 },
20215
20216 height() {
20217 this.$nextTick(() => {
20218 this.editor.resize();
20219 });
20220 },
20221 width() {
20222 this.$nextTick(() => {
20223 this.editor.resize();
20224 });
20225 }
20226 },
20227 beforeUnmount() {
20228 this.editor.destroy();
20229 this.editor.container.remove();
20230 },
20231 mounted() {
20232 let vm = this;
20233 let lang = this.lang;
20234 let theme = this.theme;
20235 let editor = vm.editor = brace.edit(this.$el);
20236 editor.getSession().setMode('ace/mode/' + lang);
20237 editor.setTheme('ace/theme/' + theme);
20238 editor.$blockScrolling = Infinity;
20239 editor.setFontSize(this.fontSize); // 设置文字大小
20240 editor.setReadOnly(this.readonly); // 设置只读
20241 editor.getSession().setUseWrapMode(this.wrap);
20242 editor.setShowPrintMargin(false);
20243 editor.getSession().setTabSize(2);
20244 editor.setOptions({
20245 enableBasicAutocompletion: this.snippets,
20246 enableSnippets: this.snippets,
20247 enableLiveAutocompletion: this.snippets
20248 });
20249 this.$emit('init', editor);
20250 if (this.modelValue) {
20251 editor.setValue(this.modelValue, 1);
20252 editor.gotoLine(0, 0, false);
20253 }
20254 this.contentBackup = this.modelValue;
20255 editor.on('change', function () {
20256 let content = editor.getValue();
20257 vm.$emit('update:modelValue', content);
20258 vm.$emit('change', content);
20259 vm.contentBackup = content;
20260 });
20261 editor.on('blur', this.handleBlur);
20262 if (vm.options) {
20263 editor.setOptions(vm.options);
20264 }
20265 }
20266};
20267
20268function render(_ctx, _cache, $props, $setup, $data, $options) {
20269 return vue.openBlock(), vue.createElementBlock("div", {
20270 class: "fei-editor",
20271 style: vue.normalizeStyle($options.wrapStyles)
20272 }, null, 4 /* STYLE */);
20273}
20274
20275script.render = render;
20276script.__file = "src/components/editor/index.vue";
20277
20278/**
20279 * @description 返回这个样式的颜色值
20280 * @param {String} type 样式名称 [ primary | success | warning | danger | text ]
20281 */
20282function typeColor(type) {
20283 if (type === void 0) {
20284 type = 'default';
20285 }
20286 let color = '';
20287 switch (type) {
20288 case 'primary':
20289 color = '#1089ff';
20290 break;
20291 case 'success':
20292 color = '#52c41a';
20293 break;
20294 case 'warning':
20295 color = '#fa8c16';
20296 break;
20297 case 'danger':
20298 color = '#f5222d';
20299 break;
20300 case 'default':
20301 color = '#35495E';
20302 break;
20303 default:
20304 color = type;
20305 break;
20306 }
20307 return color;
20308}
20309const print = function (text, type, back) {
20310 if (type === void 0) {
20311 type = 'default';
20312 }
20313 if (back === void 0) {
20314 back = false;
20315 }
20316 if (typeof text === 'object') {
20317 // 如果是对象则调用打印对象方式
20318 console.dir(text);
20319 return;
20320 }
20321 if (back) {
20322 // 如果是打印带背景图的
20323 console.log(`%c ${text} `, `background:${typeColor(type)}; padding: 2px; border-radius: 2px;color: #fff;`);
20324 } else {
20325 console.log(`%c ${text} `, `color: ${typeColor(type)};`);
20326 }
20327};
20328const pretty = function (title, text, type) {
20329 if (type === void 0) {
20330 type = 'primary';
20331 }
20332 console.log(`%c ${title} %c ${text} %c`, `background:${typeColor(type)};border:1px solid ${typeColor(type)}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`, `border:1px solid ${typeColor(type)}; padding: 1px; border-radius: 0 2px 2px 0; color: ${typeColor(type)};`, 'background:transparent');
20333};
20334const primary = function (text, back) {
20335 if (back === void 0) {
20336 back = false;
20337 }
20338 print(text, 'primary', back);
20339};
20340const success = function (text, back) {
20341 if (back === void 0) {
20342 back = false;
20343 }
20344 print(text, 'success', back);
20345};
20346const info = function (text, back) {
20347 if (back === void 0) {
20348 back = false;
20349 }
20350 print(text, 'info', back);
20351};
20352const warning = function (text, back) {
20353 if (back === void 0) {
20354 back = false;
20355 }
20356 print(text, 'warning', back);
20357};
20358const danger = function (text, back) {
20359 if (back === void 0) {
20360 back = false;
20361 }
20362 print(text, 'danger', back);
20363};
20364const printVersion = function (title, version, link, type, fontSize, versionColor) {
20365 if (type === void 0) {
20366 type = 'primary';
20367 }
20368 if (fontSize === void 0) {
20369 fontSize = '20px';
20370 }
20371 if (versionColor === void 0) {
20372 versionColor = '#999';
20373 }
20374 console.log(`%c${title.toUpperCase()} %cV${version} ${link}`, `color: ${typeColor(type)};font-weight: 500;font-size: ${fontSize};font-family: Source Sans Pro,Helvetica Neue,Arial,sans-serif;`, `color: ${versionColor};`);
20375};
20376const log = {
20377 print,
20378 pretty,
20379 primary,
20380 info,
20381 success,
20382 warning,
20383 danger,
20384 printVersion
20385};
20386
20387var name = "fei-editor";
20388var description = "基于vue的代码编辑器插件";
20389var version$1 = "0.0.2";
20390var keywords = [
20391 "fei-editor",
20392 "vue3",
20393 "components"
20394];
20395var author = "yangmengfei";
20396var files = [
20397 "lib",
20398 "src"
20399];
20400var main = "lib/fei-editor.common.js";
20401var module$1 = "src/components/editor/index.vue";
20402var unpkg = "lib/fei-editor.js";
20403var homepage = "https://ymf930.gitee.io/fei-editor/";
20404var license = "MIT";
20405var scripts = {
20406 dev: "webpack-dev-server --config build/webpack.dev.js",
20407 "build:demo": "rimraf docs && cross-env NODE_ENV=production webpack --config build/webpack.dev.js",
20408 build: "yarn clean-lib && yarn build:lib",
20409 "clean-lib": "rimraf lib",
20410 "build:lib": "rollup --config build/rollup.config.mjs --bundleConfigAsCjs",
20411 lint: "eslint ./src --ext .vue,.js,.ts",
20412 "lint-fix": "eslint --fix ./src --ext .vue,.js,.ts"
20413};
20414var dependencies = {
20415 brace: "^0.11.1"
20416};
20417var peerDependencies = {
20418 vue: "^3.2.47"
20419};
20420var devDependencies = {
20421 "@babel/cli": "^7.21.5",
20422 "@babel/core": "^7.21.8",
20423 "@babel/eslint-parser": "^7.21.8",
20424 "@babel/plugin-transform-runtime": "^7.21.4",
20425 "@babel/preset-env": "^7.21.5",
20426 "@babel/runtime": "^7.21.5",
20427 "@rollup/plugin-babel": "^6.0.3",
20428 "@rollup/plugin-commonjs": "^25.0.0",
20429 "@rollup/plugin-json": "^6.0.0",
20430 "@rollup/plugin-node-resolve": "^15.0.2",
20431 "@rollup/plugin-replace": "^5.0.2",
20432 "@rollup/plugin-terser": "^0.4.3",
20433 "@types/markdown-it": "^12.2.3",
20434 "@vue/babel-plugin-jsx": "^1.0.0",
20435 "@vue/compiler-sfc": "^3.3.4",
20436 "babel-loader": "^9.1.2",
20437 "babel-plugin-module-resolver": "^5.0.0",
20438 "babel-plugin-transform-class-properties": "^6.24.1",
20439 "cross-env": "^7.0.2",
20440 "css-loader": "^6.7.4",
20441 "css-minimizer-webpack-plugin": "^5.0.0",
20442 eslint: "^8.41.0",
20443 "eslint-plugin-vue": "^9.14.0",
20444 "f-ui-one": "^1.0.5",
20445 "file-loader": "^6.0.0",
20446 "file-save": "^0.2.0",
20447 gulp: "^4.0.2",
20448 "gulp-autoprefixer": "^8.0.0",
20449 "gulp-cssmin": "^0.2.0",
20450 "gulp-stylus": "^3.0.0",
20451 "highlight.js": "^11.8.0",
20452 "html-webpack-plugin": "^5.5.1",
20453 "markdown-it": "^13.0.1",
20454 "markdown-it-anchor": "^8.6.7",
20455 "markdown-it-chain": "^1.3.0",
20456 "markdown-it-container": "^3.0.0",
20457 "mini-css-extract-plugin": "^2.7.6",
20458 postcss: "^8.4.23",
20459 prettier: "^2.8.8",
20460 rimraf: "^5.0.1",
20461 rollup: "^3.23.0",
20462 "rollup-plugin-css-only": "^4.3.0",
20463 "rollup-plugin-peer-deps-external": "^2.2.4",
20464 "rollup-plugin-postcss": "^4.0.2",
20465 "rollup-plugin-vue": "^6.0.0-beta.11",
20466 "style-loader": "^3.3.3",
20467 stylus: "^0.59.0",
20468 "stylus-loader": "7.1.0",
20469 tinycolor2: "^1.4.2",
20470 transliteration: "^2.2.0",
20471 "url-loader": "^4.1.1",
20472 vue: "^3.3.4",
20473 "vue-loader": "^17.1.1",
20474 "vue-router": "^4.2.1",
20475 "vue-template-compiler": "^2.6.12",
20476 webpack: "^5.83.1",
20477 "webpack-bundle-analyzer": "^4.8.0",
20478 "webpack-cli": "^5.1.1",
20479 "webpack-dev-server": "^4.15.0"
20480};
20481var config = {
20482 name: name,
20483 description: description,
20484 version: version$1,
20485 keywords: keywords,
20486 author: author,
20487 files: files,
20488 main: main,
20489 module: module$1,
20490 unpkg: unpkg,
20491 homepage: homepage,
20492 "private": false,
20493 license: license,
20494 scripts: scripts,
20495 dependencies: dependencies,
20496 peerDependencies: peerDependencies,
20497 devDependencies: devDependencies
20498};
20499
20500const version = config.version; // version_ to fix tsc issue
20501
20502const install = function (app, options) {
20503 if (options === void 0) {
20504 options = {};
20505 }
20506 app.component(script.name, script);
20507 if (!options.disabledDoc) {
20508 log.printVersion(config.name, config.version, config.homepage, '#722ed1');
20509 }
20510 return app;
20511};
20512var index = {
20513 version,
20514 install
20515};
20516
20517exports.Editor = script;
20518exports.default = index;