UNPKG

707 kBJavaScriptView Raw
1/*!
2 * fei-editor v0.0.2
3 * (c) 2023 yangmengfei
4 * @license MIT
5 */
6import { openBlock, createElementBlock, normalizeStyle } from 'vue';
7
8/* ***** BEGIN LICENSE BLOCK *****
9 * Distributed under the BSD license:
10 *
11 * Copyright (c) 2010, Ajax.org B.V.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
16 * * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * * Neither the name of Ajax.org B.V. nor the
22 * names of its contributors may be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/**
39 * Define a module along with a payload
40 * @param module a name for the payload
41 * @param payload a function to call with (acequire, exports, module) params
42 */
43
44(function() {
45
46var ACE_NAMESPACE = "ace";
47
48var global = (function() { return this; })();
49if (!global && typeof window != "undefined") global = window; // strict mode
50
51
52var define = function(module, deps, payload) {
53 if (typeof module !== "string") {
54 if (define.original)
55 define.original.apply(this, arguments);
56 else {
57 console.error("dropping module because define wasn\'t a string.");
58 console.trace();
59 }
60 return;
61 }
62 if (arguments.length == 2)
63 payload = deps;
64 if (!define.modules[module]) {
65 define.payloads[module] = payload;
66 define.modules[module] = null;
67 }
68};
69
70define.modules = {};
71define.payloads = {};
72
73/**
74 * Get at functionality define()ed using the function above
75 */
76var _acequire = function(parentId, module, callback) {
77 if (typeof module === "string") {
78 var payload = lookup(parentId, module);
79 if (payload != undefined) {
80 callback && callback();
81 return payload;
82 }
83 } else if (Object.prototype.toString.call(module) === "[object Array]") {
84 var params = [];
85 for (var i = 0, l = module.length; i < l; ++i) {
86 var dep = lookup(parentId, module[i]);
87 if (dep == undefined && acequire.original)
88 return;
89 params.push(dep);
90 }
91 return callback && callback.apply(null, params) || true;
92 }
93};
94
95var acequire = function(module, callback) {
96 var packagedModule = _acequire("", module, callback);
97 if (packagedModule == undefined && acequire.original)
98 return acequire.original.apply(this, arguments);
99 return packagedModule;
100};
101
102var normalizeModule = function(parentId, moduleName) {
103 // normalize plugin acequires
104 if (moduleName.indexOf("!") !== -1) {
105 var chunks = moduleName.split("!");
106 return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
107 }
108 // normalize relative acequires
109 if (moduleName.charAt(0) == ".") {
110 var base = parentId.split("/").slice(0, -1).join("/");
111 moduleName = base + "/" + moduleName;
112
113 while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
114 var previous = moduleName;
115 moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
116 }
117 }
118 return moduleName;
119};
120
121/**
122 * Internal function to lookup moduleNames and resolve them by calling the
123 * definition function if needed.
124 */
125var lookup = function(parentId, moduleName) {
126 moduleName = normalizeModule(parentId, moduleName);
127
128 var module = define.modules[moduleName];
129 if (!module) {
130 module = define.payloads[moduleName];
131 if (typeof module === 'function') {
132 var exports = {};
133 var mod = {
134 id: moduleName,
135 uri: '',
136 exports: exports,
137 packaged: true
138 };
139
140 var req = function(module, callback) {
141 return _acequire(moduleName, module, callback);
142 };
143
144 var returnValue = module(req, exports, mod);
145 exports = returnValue || mod.exports;
146 define.modules[moduleName] = exports;
147 delete define.payloads[moduleName];
148 }
149 module = define.modules[moduleName] = exports || module;
150 }
151 return module;
152};
153
154function exportAce(ns) {
155 var root = global;
156 if (ns) {
157 if (!global[ns])
158 global[ns] = {};
159 root = global[ns];
160 }
161
162 if (!root.define || !root.define.packaged) {
163 define.original = root.define;
164 root.define = define;
165 root.define.packaged = true;
166 }
167
168 if (!root.acequire || !root.acequire.packaged) {
169 acequire.original = root.acequire;
170 root.acequire = acequire;
171 root.acequire.packaged = true;
172 }
173}
174
175exportAce(ACE_NAMESPACE);
176
177})();
178
179ace.define("ace/lib/regexp",["require","exports","module"], function(acequire, exports, module) {
180
181 var real = {
182 exec: RegExp.prototype.exec,
183 test: RegExp.prototype.test,
184 match: String.prototype.match,
185 replace: String.prototype.replace,
186 split: String.prototype.split
187 },
188 compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
189 compliantLastIndexIncrement = function () {
190 var x = /^/g;
191 real.test.call(x, "");
192 return !x.lastIndex;
193 }();
194
195 if (compliantLastIndexIncrement && compliantExecNpcg)
196 return;
197 RegExp.prototype.exec = function (str) {
198 var match = real.exec.apply(this, arguments),
199 name, r2;
200 if ( typeof(str) == 'string' && match) {
201 if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
202 r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
203 real.replace.call(str.slice(match.index), r2, function () {
204 for (var i = 1; i < arguments.length - 2; i++) {
205 if (arguments[i] === undefined)
206 match[i] = undefined;
207 }
208 });
209 }
210 if (this._xregexp && this._xregexp.captureNames) {
211 for (var i = 1; i < match.length; i++) {
212 name = this._xregexp.captureNames[i - 1];
213 if (name)
214 match[name] = match[i];
215 }
216 }
217 if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
218 this.lastIndex--;
219 }
220 return match;
221 };
222 if (!compliantLastIndexIncrement) {
223 RegExp.prototype.test = function (str) {
224 var match = real.exec.call(this, str);
225 if (match && this.global && !match[0].length && (this.lastIndex > match.index))
226 this.lastIndex--;
227 return !!match;
228 };
229 }
230
231 function getNativeFlags (regex) {
232 return (regex.global ? "g" : "") +
233 (regex.ignoreCase ? "i" : "") +
234 (regex.multiline ? "m" : "") +
235 (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3
236 (regex.sticky ? "y" : "");
237 }
238
239 function indexOf (array, item, from) {
240 if (Array.prototype.indexOf) // Use the native array method if available
241 return array.indexOf(item, from);
242 for (var i = from || 0; i < array.length; i++) {
243 if (array[i] === item)
244 return i;
245 }
246 return -1;
247 }
248
249});
250
251ace.define("ace/lib/es5-shim",["require","exports","module"], function(acequire, exports, module) {
252
253function Empty() {}
254
255if (!Function.prototype.bind) {
256 Function.prototype.bind = function bind(that) { // .length is 1
257 var target = this;
258 if (typeof target != "function") {
259 throw new TypeError("Function.prototype.bind called on incompatible " + target);
260 }
261 var args = slice.call(arguments, 1); // for normal call
262 var bound = function () {
263
264 if (this instanceof bound) {
265
266 var result = target.apply(
267 this,
268 args.concat(slice.call(arguments))
269 );
270 if (Object(result) === result) {
271 return result;
272 }
273 return this;
274
275 } else {
276 return target.apply(
277 that,
278 args.concat(slice.call(arguments))
279 );
280
281 }
282
283 };
284 if(target.prototype) {
285 Empty.prototype = target.prototype;
286 bound.prototype = new Empty();
287 Empty.prototype = null;
288 }
289 return bound;
290 };
291}
292var call = Function.prototype.call;
293var prototypeOfArray = Array.prototype;
294var prototypeOfObject = Object.prototype;
295var slice = prototypeOfArray.slice;
296var _toString = call.bind(prototypeOfObject.toString);
297var owns = call.bind(prototypeOfObject.hasOwnProperty);
298var defineGetter;
299var defineSetter;
300var lookupGetter;
301var lookupSetter;
302var supportsAccessors;
303if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
304 defineGetter = call.bind(prototypeOfObject.__defineGetter__);
305 defineSetter = call.bind(prototypeOfObject.__defineSetter__);
306 lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
307 lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
308}
309if ([1,2].splice(0).length != 2) {
310 if(function() { // test IE < 9 to splice bug - see issue #138
311 function makeArray(l) {
312 var a = new Array(l+2);
313 a[0] = a[1] = 0;
314 return a;
315 }
316 var array = [], lengthBefore;
317
318 array.splice.apply(array, makeArray(20));
319 array.splice.apply(array, makeArray(26));
320
321 lengthBefore = array.length; //46
322 array.splice(5, 0, "XXX"); // add one element
323
324 if (lengthBefore + 1 == array.length) {
325 return true;// has right splice implementation without bugs
326 }
327 }()) {//IE 6/7
328 var array_splice = Array.prototype.splice;
329 Array.prototype.splice = function(start, deleteCount) {
330 if (!arguments.length) {
331 return [];
332 } else {
333 return array_splice.apply(this, [
334 start === void 0 ? 0 : start,
335 deleteCount === void 0 ? (this.length - start) : deleteCount
336 ].concat(slice.call(arguments, 2)))
337 }
338 };
339 } else {//IE8
340 Array.prototype.splice = function(pos, removeCount){
341 var length = this.length;
342 if (pos > 0) {
343 if (pos > length)
344 pos = length;
345 } else if (pos == void 0) {
346 pos = 0;
347 } else if (pos < 0) {
348 pos = Math.max(length + pos, 0);
349 }
350
351 if (!(pos+removeCount < length))
352 removeCount = length - pos;
353
354 var removed = this.slice(pos, pos+removeCount);
355 var insert = slice.call(arguments, 2);
356 var add = insert.length;
357 if (pos === length) {
358 if (add) {
359 this.push.apply(this, insert);
360 }
361 } else {
362 var remove = Math.min(removeCount, length - pos);
363 var tailOldPos = pos + remove;
364 var tailNewPos = tailOldPos + add - remove;
365 var tailCount = length - tailOldPos;
366 var lengthAfterRemove = length - remove;
367
368 if (tailNewPos < tailOldPos) { // case A
369 for (var i = 0; i < tailCount; ++i) {
370 this[tailNewPos+i] = this[tailOldPos+i];
371 }
372 } else if (tailNewPos > tailOldPos) { // case B
373 for (i = tailCount; i--; ) {
374 this[tailNewPos+i] = this[tailOldPos+i];
375 }
376 } // else, add == remove (nothing to do)
377
378 if (add && pos === lengthAfterRemove) {
379 this.length = lengthAfterRemove; // truncate array
380 this.push.apply(this, insert);
381 } else {
382 this.length = lengthAfterRemove + add; // reserves space
383 for (i = 0; i < add; ++i) {
384 this[pos+i] = insert[i];
385 }
386 }
387 }
388 return removed;
389 };
390 }
391}
392if (!Array.isArray) {
393 Array.isArray = function isArray(obj) {
394 return _toString(obj) == "[object Array]";
395 };
396}
397var boxedString = Object("a"),
398 splitString = boxedString[0] != "a" || !(0 in boxedString);
399
400if (!Array.prototype.forEach) {
401 Array.prototype.forEach = function forEach(fun /*, thisp*/) {
402 var object = toObject(this),
403 self = splitString && _toString(this) == "[object String]" ?
404 this.split("") :
405 object,
406 thisp = arguments[1],
407 i = -1,
408 length = self.length >>> 0;
409 if (_toString(fun) != "[object Function]") {
410 throw new TypeError(); // TODO message
411 }
412
413 while (++i < length) {
414 if (i in self) {
415 fun.call(thisp, self[i], i, object);
416 }
417 }
418 };
419}
420if (!Array.prototype.map) {
421 Array.prototype.map = function map(fun /*, thisp*/) {
422 var object = toObject(this),
423 self = splitString && _toString(this) == "[object String]" ?
424 this.split("") :
425 object,
426 length = self.length >>> 0,
427 result = Array(length),
428 thisp = arguments[1];
429 if (_toString(fun) != "[object Function]") {
430 throw new TypeError(fun + " is not a function");
431 }
432
433 for (var i = 0; i < length; i++) {
434 if (i in self)
435 result[i] = fun.call(thisp, self[i], i, object);
436 }
437 return result;
438 };
439}
440if (!Array.prototype.filter) {
441 Array.prototype.filter = function filter(fun /*, thisp */) {
442 var object = toObject(this),
443 self = splitString && _toString(this) == "[object String]" ?
444 this.split("") :
445 object,
446 length = self.length >>> 0,
447 result = [],
448 value,
449 thisp = arguments[1];
450 if (_toString(fun) != "[object Function]") {
451 throw new TypeError(fun + " is not a function");
452 }
453
454 for (var i = 0; i < length; i++) {
455 if (i in self) {
456 value = self[i];
457 if (fun.call(thisp, value, i, object)) {
458 result.push(value);
459 }
460 }
461 }
462 return result;
463 };
464}
465if (!Array.prototype.every) {
466 Array.prototype.every = function every(fun /*, thisp */) {
467 var object = toObject(this),
468 self = splitString && _toString(this) == "[object String]" ?
469 this.split("") :
470 object,
471 length = self.length >>> 0,
472 thisp = arguments[1];
473 if (_toString(fun) != "[object Function]") {
474 throw new TypeError(fun + " is not a function");
475 }
476
477 for (var i = 0; i < length; i++) {
478 if (i in self && !fun.call(thisp, self[i], i, object)) {
479 return false;
480 }
481 }
482 return true;
483 };
484}
485if (!Array.prototype.some) {
486 Array.prototype.some = function some(fun /*, thisp */) {
487 var object = toObject(this),
488 self = splitString && _toString(this) == "[object String]" ?
489 this.split("") :
490 object,
491 length = self.length >>> 0,
492 thisp = arguments[1];
493 if (_toString(fun) != "[object Function]") {
494 throw new TypeError(fun + " is not a function");
495 }
496
497 for (var i = 0; i < length; i++) {
498 if (i in self && fun.call(thisp, self[i], i, object)) {
499 return true;
500 }
501 }
502 return false;
503 };
504}
505if (!Array.prototype.reduce) {
506 Array.prototype.reduce = function reduce(fun /*, initial*/) {
507 var object = toObject(this),
508 self = splitString && _toString(this) == "[object String]" ?
509 this.split("") :
510 object,
511 length = self.length >>> 0;
512 if (_toString(fun) != "[object Function]") {
513 throw new TypeError(fun + " is not a function");
514 }
515 if (!length && arguments.length == 1) {
516 throw new TypeError("reduce of empty array with no initial value");
517 }
518
519 var i = 0;
520 var result;
521 if (arguments.length >= 2) {
522 result = arguments[1];
523 } else {
524 do {
525 if (i in self) {
526 result = self[i++];
527 break;
528 }
529 if (++i >= length) {
530 throw new TypeError("reduce of empty array with no initial value");
531 }
532 } while (true);
533 }
534
535 for (; i < length; i++) {
536 if (i in self) {
537 result = fun.call(void 0, result, self[i], i, object);
538 }
539 }
540
541 return result;
542 };
543}
544if (!Array.prototype.reduceRight) {
545 Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
546 var object = toObject(this),
547 self = splitString && _toString(this) == "[object String]" ?
548 this.split("") :
549 object,
550 length = self.length >>> 0;
551 if (_toString(fun) != "[object Function]") {
552 throw new TypeError(fun + " is not a function");
553 }
554 if (!length && arguments.length == 1) {
555 throw new TypeError("reduceRight of empty array with no initial value");
556 }
557
558 var result, i = length - 1;
559 if (arguments.length >= 2) {
560 result = arguments[1];
561 } else {
562 do {
563 if (i in self) {
564 result = self[i--];
565 break;
566 }
567 if (--i < 0) {
568 throw new TypeError("reduceRight of empty array with no initial value");
569 }
570 } while (true);
571 }
572
573 do {
574 if (i in this) {
575 result = fun.call(void 0, result, self[i], i, object);
576 }
577 } while (i--);
578
579 return result;
580 };
581}
582if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
583 Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
584 var self = splitString && _toString(this) == "[object String]" ?
585 this.split("") :
586 toObject(this),
587 length = self.length >>> 0;
588
589 if (!length) {
590 return -1;
591 }
592
593 var i = 0;
594 if (arguments.length > 1) {
595 i = toInteger(arguments[1]);
596 }
597 i = i >= 0 ? i : Math.max(0, length + i);
598 for (; i < length; i++) {
599 if (i in self && self[i] === sought) {
600 return i;
601 }
602 }
603 return -1;
604 };
605}
606if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
607 Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
608 var self = splitString && _toString(this) == "[object String]" ?
609 this.split("") :
610 toObject(this),
611 length = self.length >>> 0;
612
613 if (!length) {
614 return -1;
615 }
616 var i = length - 1;
617 if (arguments.length > 1) {
618 i = Math.min(i, toInteger(arguments[1]));
619 }
620 i = i >= 0 ? i : length - Math.abs(i);
621 for (; i >= 0; i--) {
622 if (i in self && sought === self[i]) {
623 return i;
624 }
625 }
626 return -1;
627 };
628}
629if (!Object.getPrototypeOf) {
630 Object.getPrototypeOf = function getPrototypeOf(object) {
631 return object.__proto__ || (
632 object.constructor ?
633 object.constructor.prototype :
634 prototypeOfObject
635 );
636 };
637}
638if (!Object.getOwnPropertyDescriptor) {
639 var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
640 "non-object: ";
641 Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
642 if ((typeof object != "object" && typeof object != "function") || object === null)
643 throw new TypeError(ERR_NON_OBJECT + object);
644 if (!owns(object, property))
645 return;
646
647 var descriptor, getter, setter;
648 descriptor = { enumerable: true, configurable: true };
649 if (supportsAccessors) {
650 var prototype = object.__proto__;
651 object.__proto__ = prototypeOfObject;
652
653 var getter = lookupGetter(object, property);
654 var setter = lookupSetter(object, property);
655 object.__proto__ = prototype;
656
657 if (getter || setter) {
658 if (getter) descriptor.get = getter;
659 if (setter) descriptor.set = setter;
660 return descriptor;
661 }
662 }
663 descriptor.value = object[property];
664 return descriptor;
665 };
666}
667if (!Object.getOwnPropertyNames) {
668 Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
669 return Object.keys(object);
670 };
671}
672if (!Object.create) {
673 var createEmpty;
674 if (Object.prototype.__proto__ === null) {
675 createEmpty = function () {
676 return { "__proto__": null };
677 };
678 } else {
679 createEmpty = function () {
680 var empty = {};
681 for (var i in empty)
682 empty[i] = null;
683 empty.constructor =
684 empty.hasOwnProperty =
685 empty.propertyIsEnumerable =
686 empty.isPrototypeOf =
687 empty.toLocaleString =
688 empty.toString =
689 empty.valueOf =
690 empty.__proto__ = null;
691 return empty;
692 };
693 }
694
695 Object.create = function create(prototype, properties) {
696 var object;
697 if (prototype === null) {
698 object = createEmpty();
699 } else {
700 if (typeof prototype != "object")
701 throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
702 var Type = function () {};
703 Type.prototype = prototype;
704 object = new Type();
705 object.__proto__ = prototype;
706 }
707 if (properties !== void 0)
708 Object.defineProperties(object, properties);
709 return object;
710 };
711}
712
713function doesDefinePropertyWork(object) {
714 try {
715 Object.defineProperty(object, "sentinel", {});
716 return "sentinel" in object;
717 } catch (exception) {
718 }
719}
720if (Object.defineProperty) {
721 var definePropertyWorksOnObject = doesDefinePropertyWork({});
722 var definePropertyWorksOnDom = typeof document == "undefined" ||
723 doesDefinePropertyWork(document.createElement("div"));
724 if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
725 var definePropertyFallback = Object.defineProperty;
726 }
727}
728
729if (!Object.defineProperty || definePropertyFallback) {
730 var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
731 var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: ";
732 var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
733 "on this javascript engine";
734
735 Object.defineProperty = function defineProperty(object, property, descriptor) {
736 if ((typeof object != "object" && typeof object != "function") || object === null)
737 throw new TypeError(ERR_NON_OBJECT_TARGET + object);
738 if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
739 throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
740 if (definePropertyFallback) {
741 try {
742 return definePropertyFallback.call(Object, object, property, descriptor);
743 } catch (exception) {
744 }
745 }
746 if (owns(descriptor, "value")) {
747
748 if (supportsAccessors && (lookupGetter(object, property) ||
749 lookupSetter(object, property)))
750 {
751 var prototype = object.__proto__;
752 object.__proto__ = prototypeOfObject;
753 delete object[property];
754 object[property] = descriptor.value;
755 object.__proto__ = prototype;
756 } else {
757 object[property] = descriptor.value;
758 }
759 } else {
760 if (!supportsAccessors)
761 throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
762 if (owns(descriptor, "get"))
763 defineGetter(object, property, descriptor.get);
764 if (owns(descriptor, "set"))
765 defineSetter(object, property, descriptor.set);
766 }
767
768 return object;
769 };
770}
771if (!Object.defineProperties) {
772 Object.defineProperties = function defineProperties(object, properties) {
773 for (var property in properties) {
774 if (owns(properties, property))
775 Object.defineProperty(object, property, properties[property]);
776 }
777 return object;
778 };
779}
780if (!Object.seal) {
781 Object.seal = function seal(object) {
782 return object;
783 };
784}
785if (!Object.freeze) {
786 Object.freeze = function freeze(object) {
787 return object;
788 };
789}
790try {
791 Object.freeze(function () {});
792} catch (exception) {
793 Object.freeze = (function freeze(freezeObject) {
794 return function freeze(object) {
795 if (typeof object == "function") {
796 return object;
797 } else {
798 return freezeObject(object);
799 }
800 };
801 })(Object.freeze);
802}
803if (!Object.preventExtensions) {
804 Object.preventExtensions = function preventExtensions(object) {
805 return object;
806 };
807}
808if (!Object.isSealed) {
809 Object.isSealed = function isSealed(object) {
810 return false;
811 };
812}
813if (!Object.isFrozen) {
814 Object.isFrozen = function isFrozen(object) {
815 return false;
816 };
817}
818if (!Object.isExtensible) {
819 Object.isExtensible = function isExtensible(object) {
820 if (Object(object) === object) {
821 throw new TypeError(); // TODO message
822 }
823 var name = '';
824 while (owns(object, name)) {
825 name += '?';
826 }
827 object[name] = true;
828 var returnValue = owns(object, name);
829 delete object[name];
830 return returnValue;
831 };
832}
833if (!Object.keys) {
834 var hasDontEnumBug = true,
835 dontEnums = [
836 "toString",
837 "toLocaleString",
838 "valueOf",
839 "hasOwnProperty",
840 "isPrototypeOf",
841 "propertyIsEnumerable",
842 "constructor"
843 ],
844 dontEnumsLength = dontEnums.length;
845
846 for (var key in {"toString": null}) {
847 hasDontEnumBug = false;
848 }
849
850 Object.keys = function keys(object) {
851
852 if (
853 (typeof object != "object" && typeof object != "function") ||
854 object === null
855 ) {
856 throw new TypeError("Object.keys called on a non-object");
857 }
858
859 var keys = [];
860 for (var name in object) {
861 if (owns(object, name)) {
862 keys.push(name);
863 }
864 }
865
866 if (hasDontEnumBug) {
867 for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
868 var dontEnum = dontEnums[i];
869 if (owns(object, dontEnum)) {
870 keys.push(dontEnum);
871 }
872 }
873 }
874 return keys;
875 };
876
877}
878if (!Date.now) {
879 Date.now = function now() {
880 return new Date().getTime();
881 };
882}
883var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
884 "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
885 "\u2029\uFEFF";
886if (!String.prototype.trim || ws.trim()) {
887 ws = "[" + ws + "]";
888 var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
889 trimEndRegexp = new RegExp(ws + ws + "*$");
890 String.prototype.trim = function trim() {
891 return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
892 };
893}
894
895function toInteger(n) {
896 n = +n;
897 if (n !== n) { // isNaN
898 n = 0;
899 } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
900 n = (n > 0 || -1) * Math.floor(Math.abs(n));
901 }
902 return n;
903}
904var toObject = function (o) {
905 if (o == null) { // this matches both null and undefined
906 throw new TypeError("can't convert "+o+" to object");
907 }
908 return Object(o);
909};
910
911});
912
913ace.define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(acequire, exports, module) {
914
915acequire("./regexp");
916acequire("./es5-shim");
917
918});
919
920ace.define("ace/lib/dom",["require","exports","module"], function(acequire, exports, module) {
921
922var XHTML_NS = "http://www.w3.org/1999/xhtml";
923
924exports.getDocumentHead = function(doc) {
925 if (!doc)
926 doc = document;
927 return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
928};
929
930exports.createElement = function(tag, ns) {
931 return document.createElementNS ?
932 document.createElementNS(ns || XHTML_NS, tag) :
933 document.createElement(tag);
934};
935
936exports.hasCssClass = function(el, name) {
937 var classes = (el.className + "").split(/\s+/g);
938 return classes.indexOf(name) !== -1;
939};
940exports.addCssClass = function(el, name) {
941 if (!exports.hasCssClass(el, name)) {
942 el.className += " " + name;
943 }
944};
945exports.removeCssClass = function(el, name) {
946 var classes = el.className.split(/\s+/g);
947 while (true) {
948 var index = classes.indexOf(name);
949 if (index == -1) {
950 break;
951 }
952 classes.splice(index, 1);
953 }
954 el.className = classes.join(" ");
955};
956
957exports.toggleCssClass = function(el, name) {
958 var classes = el.className.split(/\s+/g), add = true;
959 while (true) {
960 var index = classes.indexOf(name);
961 if (index == -1) {
962 break;
963 }
964 add = false;
965 classes.splice(index, 1);
966 }
967 if (add)
968 classes.push(name);
969
970 el.className = classes.join(" ");
971 return add;
972};
973exports.setCssClass = function(node, className, include) {
974 if (include) {
975 exports.addCssClass(node, className);
976 } else {
977 exports.removeCssClass(node, className);
978 }
979};
980
981exports.hasCssString = function(id, doc) {
982 var index = 0, sheets;
983 doc = doc || document;
984
985 if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
986 while (index < sheets.length)
987 if (sheets[index++].owningElement.id === id) return true;
988 } else if ((sheets = doc.getElementsByTagName("style"))) {
989 while (index < sheets.length)
990 if (sheets[index++].id === id) return true;
991 }
992
993 return false;
994};
995
996exports.importCssString = function importCssString(cssText, id, doc) {
997 doc = doc || document;
998 if (id && exports.hasCssString(id, doc))
999 return null;
1000
1001 var style;
1002
1003 if (id)
1004 cssText += "\n/*# sourceURL=ace/css/" + id + " */";
1005
1006 if (doc.createStyleSheet) {
1007 style = doc.createStyleSheet();
1008 style.cssText = cssText;
1009 if (id)
1010 style.owningElement.id = id;
1011 } else {
1012 style = exports.createElement("style");
1013 style.appendChild(doc.createTextNode(cssText));
1014 if (id)
1015 style.id = id;
1016
1017 exports.getDocumentHead(doc).appendChild(style);
1018 }
1019};
1020
1021exports.importCssStylsheet = function(uri, doc) {
1022 if (doc.createStyleSheet) {
1023 doc.createStyleSheet(uri);
1024 } else {
1025 var link = exports.createElement('link');
1026 link.rel = 'stylesheet';
1027 link.href = uri;
1028
1029 exports.getDocumentHead(doc).appendChild(link);
1030 }
1031};
1032
1033exports.getInnerWidth = function(element) {
1034 return (
1035 parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
1036 parseInt(exports.computedStyle(element, "paddingRight"), 10) +
1037 element.clientWidth
1038 );
1039};
1040
1041exports.getInnerHeight = function(element) {
1042 return (
1043 parseInt(exports.computedStyle(element, "paddingTop"), 10) +
1044 parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
1045 element.clientHeight
1046 );
1047};
1048
1049exports.scrollbarWidth = function(document) {
1050 var inner = exports.createElement("ace_inner");
1051 inner.style.width = "100%";
1052 inner.style.minWidth = "0px";
1053 inner.style.height = "200px";
1054 inner.style.display = "block";
1055
1056 var outer = exports.createElement("ace_outer");
1057 var style = outer.style;
1058
1059 style.position = "absolute";
1060 style.left = "-10000px";
1061 style.overflow = "hidden";
1062 style.width = "200px";
1063 style.minWidth = "0px";
1064 style.height = "150px";
1065 style.display = "block";
1066
1067 outer.appendChild(inner);
1068
1069 var body = document.documentElement;
1070 body.appendChild(outer);
1071
1072 var noScrollbar = inner.offsetWidth;
1073
1074 style.overflow = "scroll";
1075 var withScrollbar = inner.offsetWidth;
1076
1077 if (noScrollbar == withScrollbar) {
1078 withScrollbar = outer.clientWidth;
1079 }
1080
1081 body.removeChild(outer);
1082
1083 return noScrollbar-withScrollbar;
1084};
1085
1086if (typeof document == "undefined") {
1087 exports.importCssString = function() {};
1088 return;
1089}
1090
1091if (window.pageYOffset !== undefined) {
1092 exports.getPageScrollTop = function() {
1093 return window.pageYOffset;
1094 };
1095
1096 exports.getPageScrollLeft = function() {
1097 return window.pageXOffset;
1098 };
1099}
1100else {
1101 exports.getPageScrollTop = function() {
1102 return document.body.scrollTop;
1103 };
1104
1105 exports.getPageScrollLeft = function() {
1106 return document.body.scrollLeft;
1107 };
1108}
1109
1110if (window.getComputedStyle)
1111 exports.computedStyle = function(element, style) {
1112 if (style)
1113 return (window.getComputedStyle(element, "") || {})[style] || "";
1114 return window.getComputedStyle(element, "") || {};
1115 };
1116else
1117 exports.computedStyle = function(element, style) {
1118 if (style)
1119 return element.currentStyle[style];
1120 return element.currentStyle;
1121 };
1122exports.setInnerHtml = function(el, innerHtml) {
1123 var element = el.cloneNode(false);//document.createElement("div");
1124 element.innerHTML = innerHtml;
1125 el.parentNode.replaceChild(element, el);
1126 return element;
1127};
1128
1129if ("textContent" in document.documentElement) {
1130 exports.setInnerText = function(el, innerText) {
1131 el.textContent = innerText;
1132 };
1133
1134 exports.getInnerText = function(el) {
1135 return el.textContent;
1136 };
1137}
1138else {
1139 exports.setInnerText = function(el, innerText) {
1140 el.innerText = innerText;
1141 };
1142
1143 exports.getInnerText = function(el) {
1144 return el.innerText;
1145 };
1146}
1147
1148exports.getParentWindow = function(document) {
1149 return document.defaultView || document.parentWindow;
1150};
1151
1152});
1153
1154ace.define("ace/lib/oop",["require","exports","module"], function(acequire, exports, module) {
1155
1156exports.inherits = function(ctor, superCtor) {
1157 ctor.super_ = superCtor;
1158 ctor.prototype = Object.create(superCtor.prototype, {
1159 constructor: {
1160 value: ctor,
1161 enumerable: false,
1162 writable: true,
1163 configurable: true
1164 }
1165 });
1166};
1167
1168exports.mixin = function(obj, mixin) {
1169 for (var key in mixin) {
1170 obj[key] = mixin[key];
1171 }
1172 return obj;
1173};
1174
1175exports.implement = function(proto, mixin) {
1176 exports.mixin(proto, mixin);
1177};
1178
1179});
1180
1181ace.define("ace/lib/keys",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop"], function(acequire, exports, module) {
1182
1183acequire("./fixoldbrowsers");
1184
1185var oop = acequire("./oop");
1186var Keys = (function() {
1187 var ret = {
1188 MODIFIER_KEYS: {
1189 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
1190 },
1191
1192 KEY_MODS: {
1193 "ctrl": 1, "alt": 2, "option" : 2, "shift": 4,
1194 "super": 8, "meta": 8, "command": 8, "cmd": 8
1195 },
1196
1197 FUNCTION_KEYS : {
1198 8 : "Backspace",
1199 9 : "Tab",
1200 13 : "Return",
1201 19 : "Pause",
1202 27 : "Esc",
1203 32 : "Space",
1204 33 : "PageUp",
1205 34 : "PageDown",
1206 35 : "End",
1207 36 : "Home",
1208 37 : "Left",
1209 38 : "Up",
1210 39 : "Right",
1211 40 : "Down",
1212 44 : "Print",
1213 45 : "Insert",
1214 46 : "Delete",
1215 96 : "Numpad0",
1216 97 : "Numpad1",
1217 98 : "Numpad2",
1218 99 : "Numpad3",
1219 100: "Numpad4",
1220 101: "Numpad5",
1221 102: "Numpad6",
1222 103: "Numpad7",
1223 104: "Numpad8",
1224 105: "Numpad9",
1225 '-13': "NumpadEnter",
1226 112: "F1",
1227 113: "F2",
1228 114: "F3",
1229 115: "F4",
1230 116: "F5",
1231 117: "F6",
1232 118: "F7",
1233 119: "F8",
1234 120: "F9",
1235 121: "F10",
1236 122: "F11",
1237 123: "F12",
1238 144: "Numlock",
1239 145: "Scrolllock"
1240 },
1241
1242 PRINTABLE_KEYS: {
1243 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5',
1244 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a',
1245 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h',
1246 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',
1247 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
1248 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
1249 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',
1250 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*'
1251 }
1252 };
1253 var name, i;
1254 for (i in ret.FUNCTION_KEYS) {
1255 name = ret.FUNCTION_KEYS[i].toLowerCase();
1256 ret[name] = parseInt(i, 10);
1257 }
1258 for (i in ret.PRINTABLE_KEYS) {
1259 name = ret.PRINTABLE_KEYS[i].toLowerCase();
1260 ret[name] = parseInt(i, 10);
1261 }
1262 oop.mixin(ret, ret.MODIFIER_KEYS);
1263 oop.mixin(ret, ret.PRINTABLE_KEYS);
1264 oop.mixin(ret, ret.FUNCTION_KEYS);
1265 ret.enter = ret["return"];
1266 ret.escape = ret.esc;
1267 ret.del = ret["delete"];
1268 ret[173] = '-';
1269
1270 (function() {
1271 var mods = ["cmd", "ctrl", "alt", "shift"];
1272 for (var i = Math.pow(2, mods.length); i--;) {
1273 ret.KEY_MODS[i] = mods.filter(function(x) {
1274 return i & ret.KEY_MODS[x];
1275 }).join("-") + "-";
1276 }
1277 })();
1278
1279 ret.KEY_MODS[0] = "";
1280 ret.KEY_MODS[-1] = "input-";
1281
1282 return ret;
1283})();
1284oop.mixin(exports, Keys);
1285
1286exports.keyCodeToString = function(keyCode) {
1287 var keyString = Keys[keyCode];
1288 if (typeof keyString != "string")
1289 keyString = String.fromCharCode(keyCode);
1290 return keyString.toLowerCase();
1291};
1292
1293});
1294
1295ace.define("ace/lib/useragent",["require","exports","module"], function(acequire, exports, module) {
1296exports.OS = {
1297 LINUX: "LINUX",
1298 MAC: "MAC",
1299 WINDOWS: "WINDOWS"
1300};
1301exports.getOS = function() {
1302 if (exports.isMac) {
1303 return exports.OS.MAC;
1304 } else if (exports.isLinux) {
1305 return exports.OS.LINUX;
1306 } else {
1307 return exports.OS.WINDOWS;
1308 }
1309};
1310if (typeof navigator != "object")
1311 return;
1312
1313var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
1314var ua = navigator.userAgent;
1315exports.isWin = (os == "win");
1316exports.isMac = (os == "mac");
1317exports.isLinux = (os == "linux");
1318exports.isIE =
1319 (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
1320 ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1])
1321 : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie
1322
1323exports.isOldIE = exports.isIE && exports.isIE < 9;
1324exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko";
1325exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv:(\d+)/)||[])[1], 10) < 4;
1326exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
1327exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
1328
1329exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
1330
1331exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
1332
1333exports.isIPad = ua.indexOf("iPad") >= 0;
1334
1335exports.isChromeOS = ua.indexOf(" CrOS ") >= 0;
1336
1337exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
1338
1339if (exports.isIOS) exports.isMac = true;
1340
1341});
1342
1343ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(acequire, exports, module) {
1344
1345var keys = acequire("./keys");
1346var useragent = acequire("./useragent");
1347
1348var pressedKeys = null;
1349var ts = 0;
1350
1351exports.addListener = function(elem, type, callback) {
1352 if (elem.addEventListener) {
1353 return elem.addEventListener(type, callback, false);
1354 }
1355 if (elem.attachEvent) {
1356 var wrapper = function() {
1357 callback.call(elem, window.event);
1358 };
1359 callback._wrapper = wrapper;
1360 elem.attachEvent("on" + type, wrapper);
1361 }
1362};
1363
1364exports.removeListener = function(elem, type, callback) {
1365 if (elem.removeEventListener) {
1366 return elem.removeEventListener(type, callback, false);
1367 }
1368 if (elem.detachEvent) {
1369 elem.detachEvent("on" + type, callback._wrapper || callback);
1370 }
1371};
1372exports.stopEvent = function(e) {
1373 exports.stopPropagation(e);
1374 exports.preventDefault(e);
1375 return false;
1376};
1377
1378exports.stopPropagation = function(e) {
1379 if (e.stopPropagation)
1380 e.stopPropagation();
1381 else
1382 e.cancelBubble = true;
1383};
1384
1385exports.preventDefault = function(e) {
1386 if (e.preventDefault)
1387 e.preventDefault();
1388 else
1389 e.returnValue = false;
1390};
1391exports.getButton = function(e) {
1392 if (e.type == "dblclick")
1393 return 0;
1394 if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
1395 return 2;
1396 if (e.preventDefault) {
1397 return e.button;
1398 }
1399 else {
1400 return {1:0, 2:2, 4:1}[e.button];
1401 }
1402};
1403
1404exports.capture = function(el, eventHandler, releaseCaptureHandler) {
1405 function onMouseUp(e) {
1406 eventHandler && eventHandler(e);
1407 releaseCaptureHandler && releaseCaptureHandler(e);
1408
1409 exports.removeListener(document, "mousemove", eventHandler, true);
1410 exports.removeListener(document, "mouseup", onMouseUp, true);
1411 exports.removeListener(document, "dragstart", onMouseUp, true);
1412 }
1413
1414 exports.addListener(document, "mousemove", eventHandler, true);
1415 exports.addListener(document, "mouseup", onMouseUp, true);
1416 exports.addListener(document, "dragstart", onMouseUp, true);
1417
1418 return onMouseUp;
1419};
1420
1421exports.addTouchMoveListener = function (el, callback) {
1422 var startx, starty;
1423 exports.addListener(el, "touchstart", function (e) {
1424 var touches = e.touches;
1425 var touchObj = touches[0];
1426 startx = touchObj.clientX;
1427 starty = touchObj.clientY;
1428 });
1429 exports.addListener(el, "touchmove", function (e) {
1430 var touches = e.touches;
1431 if (touches.length > 1) return;
1432
1433 var touchObj = touches[0];
1434
1435 e.wheelX = startx - touchObj.clientX;
1436 e.wheelY = starty - touchObj.clientY;
1437
1438 startx = touchObj.clientX;
1439 starty = touchObj.clientY;
1440
1441 callback(e);
1442 });
1443};
1444
1445exports.addMouseWheelListener = function(el, callback) {
1446 if ("onmousewheel" in el) {
1447 exports.addListener(el, "mousewheel", function(e) {
1448 var factor = 8;
1449 if (e.wheelDeltaX !== undefined) {
1450 e.wheelX = -e.wheelDeltaX / factor;
1451 e.wheelY = -e.wheelDeltaY / factor;
1452 } else {
1453 e.wheelX = 0;
1454 e.wheelY = -e.wheelDelta / factor;
1455 }
1456 callback(e);
1457 });
1458 } else if ("onwheel" in el) {
1459 exports.addListener(el, "wheel", function(e) {
1460 var factor = 0.35;
1461 switch (e.deltaMode) {
1462 case e.DOM_DELTA_PIXEL:
1463 e.wheelX = e.deltaX * factor || 0;
1464 e.wheelY = e.deltaY * factor || 0;
1465 break;
1466 case e.DOM_DELTA_LINE:
1467 case e.DOM_DELTA_PAGE:
1468 e.wheelX = (e.deltaX || 0) * 5;
1469 e.wheelY = (e.deltaY || 0) * 5;
1470 break;
1471 }
1472
1473 callback(e);
1474 });
1475 } else {
1476 exports.addListener(el, "DOMMouseScroll", function(e) {
1477 if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
1478 e.wheelX = (e.detail || 0) * 5;
1479 e.wheelY = 0;
1480 } else {
1481 e.wheelX = 0;
1482 e.wheelY = (e.detail || 0) * 5;
1483 }
1484 callback(e);
1485 });
1486 }
1487};
1488
1489exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName) {
1490 var clicks = 0;
1491 var startX, startY, timer;
1492 var eventNames = {
1493 2: "dblclick",
1494 3: "tripleclick",
1495 4: "quadclick"
1496 };
1497
1498 function onMousedown(e) {
1499 if (exports.getButton(e) !== 0) {
1500 clicks = 0;
1501 } else if (e.detail > 1) {
1502 clicks++;
1503 if (clicks > 4)
1504 clicks = 1;
1505 } else {
1506 clicks = 1;
1507 }
1508 if (useragent.isIE) {
1509 var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
1510 if (!timer || isNewClick)
1511 clicks = 1;
1512 if (timer)
1513 clearTimeout(timer);
1514 timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
1515
1516 if (clicks == 1) {
1517 startX = e.clientX;
1518 startY = e.clientY;
1519 }
1520 }
1521
1522 e._clicks = clicks;
1523
1524 eventHandler[callbackName]("mousedown", e);
1525
1526 if (clicks > 4)
1527 clicks = 0;
1528 else if (clicks > 1)
1529 return eventHandler[callbackName](eventNames[clicks], e);
1530 }
1531 function onDblclick(e) {
1532 clicks = 2;
1533 if (timer)
1534 clearTimeout(timer);
1535 timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
1536 eventHandler[callbackName]("mousedown", e);
1537 eventHandler[callbackName](eventNames[clicks], e);
1538 }
1539 if (!Array.isArray(elements))
1540 elements = [elements];
1541 elements.forEach(function(el) {
1542 exports.addListener(el, "mousedown", onMousedown);
1543 if (useragent.isOldIE)
1544 exports.addListener(el, "dblclick", onDblclick);
1545 });
1546};
1547
1548var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window)
1549 ? function(e) {
1550 return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
1551 }
1552 : function(e) {
1553 return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
1554 };
1555
1556exports.getModifierString = function(e) {
1557 return keys.KEY_MODS[getModifierHash(e)];
1558};
1559
1560function normalizeCommandKeys(callback, e, keyCode) {
1561 var hashId = getModifierHash(e);
1562
1563 if (!useragent.isMac && pressedKeys) {
1564 if (e.getModifierState && (e.getModifierState("OS") || e.getModifierState("Win")))
1565 hashId |= 8;
1566 if (pressedKeys.altGr) {
1567 if ((3 & hashId) != 3)
1568 pressedKeys.altGr = 0;
1569 else
1570 return;
1571 }
1572 if (keyCode === 18 || keyCode === 17) {
1573 var location = "location" in e ? e.location : e.keyLocation;
1574 if (keyCode === 17 && location === 1) {
1575 if (pressedKeys[keyCode] == 1)
1576 ts = e.timeStamp;
1577 } else if (keyCode === 18 && hashId === 3 && location === 2) {
1578 var dt = e.timeStamp - ts;
1579 if (dt < 50)
1580 pressedKeys.altGr = true;
1581 }
1582 }
1583 }
1584
1585 if (keyCode in keys.MODIFIER_KEYS) {
1586 keyCode = -1;
1587 }
1588 if (hashId & 8 && (keyCode >= 91 && keyCode <= 93)) {
1589 keyCode = -1;
1590 }
1591
1592 if (!hashId && keyCode === 13) {
1593 var location = "location" in e ? e.location : e.keyLocation;
1594 if (location === 3) {
1595 callback(e, hashId, -keyCode);
1596 if (e.defaultPrevented)
1597 return;
1598 }
1599 }
1600
1601 if (useragent.isChromeOS && hashId & 8) {
1602 callback(e, hashId, keyCode);
1603 if (e.defaultPrevented)
1604 return;
1605 else
1606 hashId &= ~8;
1607 }
1608 if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
1609 return false;
1610 }
1611
1612 return callback(e, hashId, keyCode);
1613}
1614
1615
1616exports.addCommandKeyListener = function(el, callback) {
1617 var addListener = exports.addListener;
1618 if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
1619 var lastKeyDownKeyCode = null;
1620 addListener(el, "keydown", function(e) {
1621 lastKeyDownKeyCode = e.keyCode;
1622 });
1623 addListener(el, "keypress", function(e) {
1624 return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);
1625 });
1626 } else {
1627 var lastDefaultPrevented = null;
1628
1629 addListener(el, "keydown", function(e) {
1630 pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1;
1631 var result = normalizeCommandKeys(callback, e, e.keyCode);
1632 lastDefaultPrevented = e.defaultPrevented;
1633 return result;
1634 });
1635
1636 addListener(el, "keypress", function(e) {
1637 if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {
1638 exports.stopEvent(e);
1639 lastDefaultPrevented = null;
1640 }
1641 });
1642
1643 addListener(el, "keyup", function(e) {
1644 pressedKeys[e.keyCode] = null;
1645 });
1646
1647 if (!pressedKeys) {
1648 resetPressedKeys();
1649 addListener(window, "focus", resetPressedKeys);
1650 }
1651 }
1652};
1653function resetPressedKeys() {
1654 pressedKeys = Object.create(null);
1655}
1656
1657if (typeof window == "object" && window.postMessage && !useragent.isOldIE) {
1658 var postMessageId = 1;
1659 exports.nextTick = function(callback, win) {
1660 win = win || window;
1661 var messageName = "zero-timeout-message-" + postMessageId;
1662 exports.addListener(win, "message", function listener(e) {
1663 if (e.data == messageName) {
1664 exports.stopPropagation(e);
1665 exports.removeListener(win, "message", listener);
1666 callback();
1667 }
1668 });
1669 win.postMessage(messageName, "*");
1670 };
1671}
1672
1673
1674exports.nextFrame = typeof window == "object" && (window.requestAnimationFrame
1675 || window.mozRequestAnimationFrame
1676 || window.webkitRequestAnimationFrame
1677 || window.msRequestAnimationFrame
1678 || window.oRequestAnimationFrame);
1679
1680if (exports.nextFrame)
1681 exports.nextFrame = exports.nextFrame.bind(window);
1682else
1683 exports.nextFrame = function(callback) {
1684 setTimeout(callback, 17);
1685 };
1686});
1687
1688ace.define("ace/lib/lang",["require","exports","module"], function(acequire, exports, module) {
1689
1690exports.last = function(a) {
1691 return a[a.length - 1];
1692};
1693
1694exports.stringReverse = function(string) {
1695 return string.split("").reverse().join("");
1696};
1697
1698exports.stringRepeat = function (string, count) {
1699 var result = '';
1700 while (count > 0) {
1701 if (count & 1)
1702 result += string;
1703
1704 if (count >>= 1)
1705 string += string;
1706 }
1707 return result;
1708};
1709
1710var trimBeginRegexp = /^\s\s*/;
1711var trimEndRegexp = /\s\s*$/;
1712
1713exports.stringTrimLeft = function (string) {
1714 return string.replace(trimBeginRegexp, '');
1715};
1716
1717exports.stringTrimRight = function (string) {
1718 return string.replace(trimEndRegexp, '');
1719};
1720
1721exports.copyObject = function(obj) {
1722 var copy = {};
1723 for (var key in obj) {
1724 copy[key] = obj[key];
1725 }
1726 return copy;
1727};
1728
1729exports.copyArray = function(array){
1730 var copy = [];
1731 for (var i=0, l=array.length; i<l; i++) {
1732 if (array[i] && typeof array[i] == "object")
1733 copy[i] = this.copyObject(array[i]);
1734 else
1735 copy[i] = array[i];
1736 }
1737 return copy;
1738};
1739
1740exports.deepCopy = function deepCopy(obj) {
1741 if (typeof obj !== "object" || !obj)
1742 return obj;
1743 var copy;
1744 if (Array.isArray(obj)) {
1745 copy = [];
1746 for (var key = 0; key < obj.length; key++) {
1747 copy[key] = deepCopy(obj[key]);
1748 }
1749 return copy;
1750 }
1751 if (Object.prototype.toString.call(obj) !== "[object Object]")
1752 return obj;
1753
1754 copy = {};
1755 for (var key in obj)
1756 copy[key] = deepCopy(obj[key]);
1757 return copy;
1758};
1759
1760exports.arrayToMap = function(arr) {
1761 var map = {};
1762 for (var i=0; i<arr.length; i++) {
1763 map[arr[i]] = 1;
1764 }
1765 return map;
1766
1767};
1768
1769exports.createMap = function(props) {
1770 var map = Object.create(null);
1771 for (var i in props) {
1772 map[i] = props[i];
1773 }
1774 return map;
1775};
1776exports.arrayRemove = function(array, value) {
1777 for (var i = 0; i <= array.length; i++) {
1778 if (value === array[i]) {
1779 array.splice(i, 1);
1780 }
1781 }
1782};
1783
1784exports.escapeRegExp = function(str) {
1785 return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1786};
1787
1788exports.escapeHTML = function(str) {
1789 return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
1790};
1791
1792exports.getMatchOffsets = function(string, regExp) {
1793 var matches = [];
1794
1795 string.replace(regExp, function(str) {
1796 matches.push({
1797 offset: arguments[arguments.length-2],
1798 length: str.length
1799 });
1800 });
1801
1802 return matches;
1803};
1804exports.deferredCall = function(fcn) {
1805 var timer = null;
1806 var callback = function() {
1807 timer = null;
1808 fcn();
1809 };
1810
1811 var deferred = function(timeout) {
1812 deferred.cancel();
1813 timer = setTimeout(callback, timeout || 0);
1814 return deferred;
1815 };
1816
1817 deferred.schedule = deferred;
1818
1819 deferred.call = function() {
1820 this.cancel();
1821 fcn();
1822 return deferred;
1823 };
1824
1825 deferred.cancel = function() {
1826 clearTimeout(timer);
1827 timer = null;
1828 return deferred;
1829 };
1830
1831 deferred.isPending = function() {
1832 return timer;
1833 };
1834
1835 return deferred;
1836};
1837
1838
1839exports.delayedCall = function(fcn, defaultTimeout) {
1840 var timer = null;
1841 var callback = function() {
1842 timer = null;
1843 fcn();
1844 };
1845
1846 var _self = function(timeout) {
1847 if (timer == null)
1848 timer = setTimeout(callback, timeout || defaultTimeout);
1849 };
1850
1851 _self.delay = function(timeout) {
1852 timer && clearTimeout(timer);
1853 timer = setTimeout(callback, timeout || defaultTimeout);
1854 };
1855 _self.schedule = _self;
1856
1857 _self.call = function() {
1858 this.cancel();
1859 fcn();
1860 };
1861
1862 _self.cancel = function() {
1863 timer && clearTimeout(timer);
1864 timer = null;
1865 };
1866
1867 _self.isPending = function() {
1868 return timer;
1869 };
1870
1871 return _self;
1872};
1873});
1874
1875ace.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) {
1876
1877var event = acequire("../lib/event");
1878var useragent = acequire("../lib/useragent");
1879var dom = acequire("../lib/dom");
1880var lang = acequire("../lib/lang");
1881var KEYS = acequire("../lib/keys");
1882var MODS = KEYS.KEY_MODS;
1883var BROKEN_SETDATA = useragent.isChrome < 18;
1884var USE_IE_MIME_TYPE = useragent.isIE;
1885
1886var TextInput = function(parentNode, host) {
1887 var text = dom.createElement("textarea");
1888 text.className = useragent.isIOS ? "ace_text-input ace_text-input-ios" : "ace_text-input";
1889
1890 if (useragent.isTouchPad)
1891 text.setAttribute("x-palm-disable-auto-cap", true);
1892
1893 text.setAttribute("wrap", "off");
1894 text.setAttribute("autocorrect", "off");
1895 text.setAttribute("autocapitalize", "off");
1896 text.setAttribute("spellcheck", false);
1897
1898 text.style.opacity = "0";
1899 parentNode.insertBefore(text, parentNode.firstChild);
1900
1901 var PLACEHOLDER = "\n aaaa a\n";
1902
1903 var copied = false;
1904 var cut = false;
1905 var pasted = false;
1906 var inComposition = false;
1907 var tempStyle = '';
1908 var isSelectionEmpty = true;
1909 try { var isFocused = document.activeElement === text; } catch(e) {}
1910
1911 event.addListener(text, "blur", function(e) {
1912 host.onBlur(e);
1913 isFocused = false;
1914 });
1915 event.addListener(text, "focus", function(e) {
1916 isFocused = true;
1917 host.onFocus(e);
1918 resetSelection();
1919 });
1920 this.focus = function() {
1921 if (tempStyle) return text.focus();
1922 text.style.position = "fixed";
1923 text.focus();
1924 };
1925 this.blur = function() {
1926 text.blur();
1927 };
1928 this.isFocused = function() {
1929 return isFocused;
1930 };
1931 var syncSelection = lang.delayedCall(function() {
1932 isFocused && resetSelection(isSelectionEmpty);
1933 });
1934 var syncValue = lang.delayedCall(function() {
1935 if (!inComposition) {
1936 text.value = PLACEHOLDER;
1937 isFocused && resetSelection();
1938 }
1939 });
1940
1941 function resetSelection(isEmpty) {
1942 if (inComposition)
1943 return;
1944 inComposition = true;
1945
1946 if (inputHandler) {
1947 selectionStart = 0;
1948 selectionEnd = isEmpty ? 0 : text.value.length - 1;
1949 } else {
1950 var selectionStart = 4;
1951 var selectionEnd = 5;
1952 }
1953 try {
1954 text.setSelectionRange(selectionStart, selectionEnd);
1955 } catch(e) {}
1956
1957 inComposition = false;
1958 }
1959
1960 function resetValue() {
1961 if (inComposition)
1962 return;
1963 text.value = PLACEHOLDER;
1964 if (useragent.isWebKit)
1965 syncValue.schedule();
1966 }
1967
1968 useragent.isWebKit || host.addEventListener('changeSelection', function() {
1969 if (host.selection.isEmpty() != isSelectionEmpty) {
1970 isSelectionEmpty = !isSelectionEmpty;
1971 syncSelection.schedule();
1972 }
1973 });
1974
1975 resetValue();
1976 if (isFocused)
1977 host.onFocus();
1978
1979
1980 var isAllSelected = function(text) {
1981 return text.selectionStart === 0 && text.selectionEnd === text.value.length;
1982 };
1983
1984 var onSelect = function(e) {
1985 if (isAllSelected(text)) {
1986 host.selectAll();
1987 resetSelection();
1988 } else if (inputHandler) {
1989 resetSelection(host.selection.isEmpty());
1990 }
1991 };
1992
1993 var inputHandler = null;
1994 this.setInputHandler = function(cb) {inputHandler = cb;};
1995 this.getInputHandler = function() {return inputHandler;};
1996 var afterContextMenu = false;
1997
1998 var sendText = function(data) {
1999 if (text.selectionStart === 4 && text.selectionEnd === 5) {
2000 return;
2001 }
2002 if (inputHandler) {
2003 data = inputHandler(data);
2004 inputHandler = null;
2005 }
2006 if (pasted) {
2007 resetSelection();
2008 if (data)
2009 host.onPaste(data);
2010 pasted = false;
2011 } else if (data == PLACEHOLDER.substr(0) && text.selectionStart === 4) {
2012 if (afterContextMenu)
2013 host.execCommand("del", {source: "ace"});
2014 else // some versions of android do not fire keydown when pressing backspace
2015 host.execCommand("backspace", {source: "ace"});
2016 } else if (!copied) {
2017 if (data.substring(0, 9) == PLACEHOLDER && data.length > PLACEHOLDER.length)
2018 data = data.substr(9);
2019 else if (data.substr(0, 4) == PLACEHOLDER.substr(0, 4))
2020 data = data.substr(4, data.length - PLACEHOLDER.length + 1);
2021 else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2022 data = data.slice(0, -1);
2023 if (data == PLACEHOLDER.charAt(0)) ; else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2024 data = data.slice(0, -1);
2025
2026 if (data)
2027 host.onTextInput(data);
2028 }
2029 if (copied) {
2030 copied = false;
2031 }
2032 if (afterContextMenu)
2033 afterContextMenu = false;
2034 };
2035 var onInput = function(e) {
2036 if (inComposition)
2037 return;
2038 var data = text.value;
2039 sendText(data);
2040 resetValue();
2041 };
2042
2043 var handleClipboardData = function(e, data, forceIEMime) {
2044 var clipboardData = e.clipboardData || window.clipboardData;
2045 if (!clipboardData || BROKEN_SETDATA)
2046 return;
2047 var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain";
2048 try {
2049 if (data) {
2050 return clipboardData.setData(mime, data) !== false;
2051 } else {
2052 return clipboardData.getData(mime);
2053 }
2054 } catch(e) {
2055 if (!forceIEMime)
2056 return handleClipboardData(e, data, true);
2057 }
2058 };
2059
2060 var doCopy = function(e, isCut) {
2061 var data = host.getCopyText();
2062 if (!data)
2063 return event.preventDefault(e);
2064
2065 if (handleClipboardData(e, data)) {
2066 if (useragent.isIOS) {
2067 cut = isCut;
2068 text.value = "\n aa" + data + "a a\n";
2069 text.setSelectionRange(4, 4 + data.length);
2070 copied = {
2071 value: data
2072 };
2073 }
2074 isCut ? host.onCut() : host.onCopy();
2075 if (!useragent.isIOS) event.preventDefault(e);
2076 } else {
2077 copied = true;
2078 text.value = data;
2079 text.select();
2080 setTimeout(function(){
2081 copied = false;
2082 resetValue();
2083 resetSelection();
2084 isCut ? host.onCut() : host.onCopy();
2085 });
2086 }
2087 };
2088
2089 var onCut = function(e) {
2090 doCopy(e, true);
2091 };
2092
2093 var onCopy = function(e) {
2094 doCopy(e, false);
2095 };
2096
2097 var onPaste = function(e) {
2098 var data = handleClipboardData(e);
2099 if (typeof data == "string") {
2100 if (data)
2101 host.onPaste(data, e);
2102 if (useragent.isIE)
2103 setTimeout(resetSelection);
2104 event.preventDefault(e);
2105 }
2106 else {
2107 text.value = "";
2108 pasted = true;
2109 }
2110 };
2111
2112 event.addCommandKeyListener(text, host.onCommandKey.bind(host));
2113
2114 event.addListener(text, "select", onSelect);
2115
2116 event.addListener(text, "input", onInput);
2117
2118 event.addListener(text, "cut", onCut);
2119 event.addListener(text, "copy", onCopy);
2120 event.addListener(text, "paste", onPaste);
2121 var onCompositionStart = function(e) {
2122 if (inComposition || !host.onCompositionStart || host.$readOnly)
2123 return;
2124 inComposition = {};
2125 inComposition.canUndo = host.session.$undoManager;
2126 host.onCompositionStart();
2127 setTimeout(onCompositionUpdate, 0);
2128 host.on("mousedown", onCompositionEnd);
2129 if (inComposition.canUndo && !host.selection.isEmpty()) {
2130 host.insert("");
2131 host.session.markUndoGroup();
2132 host.selection.clearSelection();
2133 }
2134 host.session.markUndoGroup();
2135 };
2136
2137 var onCompositionUpdate = function() {
2138 if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
2139 return;
2140 var val = text.value.replace(/\x01/g, "");
2141 if (inComposition.lastValue === val) return;
2142
2143 host.onCompositionUpdate(val);
2144 if (inComposition.lastValue)
2145 host.undo();
2146 if (inComposition.canUndo)
2147 inComposition.lastValue = val;
2148 if (inComposition.lastValue) {
2149 var r = host.selection.getRange();
2150 host.insert(inComposition.lastValue);
2151 host.session.markUndoGroup();
2152 inComposition.range = host.selection.getRange();
2153 host.selection.setRange(r);
2154 host.selection.clearSelection();
2155 }
2156 };
2157
2158 var onCompositionEnd = function(e) {
2159 if (!host.onCompositionEnd || host.$readOnly) return;
2160 var c = inComposition;
2161 inComposition = false;
2162 var timer = setTimeout(function() {
2163 timer = null;
2164 var str = text.value.replace(/\x01/g, "");
2165 if (inComposition)
2166 return;
2167 else if (str == c.lastValue)
2168 resetValue();
2169 else if (!c.lastValue && str) {
2170 resetValue();
2171 sendText(str);
2172 }
2173 });
2174 inputHandler = function compositionInputHandler(str) {
2175 if (timer)
2176 clearTimeout(timer);
2177 str = str.replace(/\x01/g, "");
2178 if (str == c.lastValue)
2179 return "";
2180 if (c.lastValue && timer)
2181 host.undo();
2182 return str;
2183 };
2184 host.onCompositionEnd();
2185 host.removeListener("mousedown", onCompositionEnd);
2186 if (e.type == "compositionend" && c.range) {
2187 host.selection.setRange(c.range);
2188 }
2189 var needsOnInput =
2190 (!!useragent.isChrome && useragent.isChrome >= 53) ||
2191 (!!useragent.isWebKit && useragent.isWebKit >= 603);
2192
2193 if (needsOnInput) {
2194 onInput();
2195 }
2196 };
2197
2198
2199
2200 var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
2201
2202 event.addListener(text, "compositionstart", onCompositionStart);
2203 if (useragent.isGecko) {
2204 event.addListener(text, "text", function(){syncComposition.schedule();});
2205 } else {
2206 event.addListener(text, "keyup", function(){syncComposition.schedule();});
2207 event.addListener(text, "keydown", function(){syncComposition.schedule();});
2208 }
2209 event.addListener(text, "compositionend", onCompositionEnd);
2210
2211 this.getElement = function() {
2212 return text;
2213 };
2214
2215 this.setReadOnly = function(readOnly) {
2216 text.readOnly = readOnly;
2217 };
2218
2219 this.onContextMenu = function(e) {
2220 afterContextMenu = true;
2221 resetSelection(host.selection.isEmpty());
2222 host._emit("nativecontextmenu", {target: host, domEvent: e});
2223 this.moveToMouse(e, true);
2224 };
2225
2226 this.moveToMouse = function(e, bringToFront) {
2227 if (!tempStyle)
2228 tempStyle = text.style.cssText;
2229 text.style.cssText = (bringToFront ? "z-index:100000;" : "")
2230 + "height:" + text.style.height + ";"
2231 + (useragent.isIE ? "opacity:0.1;" : "");
2232
2233 var rect = host.container.getBoundingClientRect();
2234 var style = dom.computedStyle(host.container);
2235 var top = rect.top + (parseInt(style.borderTopWidth) || 0);
2236 var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
2237 var maxTop = rect.bottom - top - text.clientHeight -2;
2238 var move = function(e) {
2239 text.style.left = e.clientX - left - 2 + "px";
2240 text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
2241 };
2242 move(e);
2243
2244 if (e.type != "mousedown")
2245 return;
2246
2247 if (host.renderer.$keepTextAreaAtCursor)
2248 host.renderer.$keepTextAreaAtCursor = null;
2249
2250 clearTimeout(closeTimeout);
2251 if (useragent.isWin)
2252 event.capture(host.container, move, onContextMenuClose);
2253 };
2254
2255 this.onContextMenuClose = onContextMenuClose;
2256 var closeTimeout;
2257 function onContextMenuClose() {
2258 clearTimeout(closeTimeout);
2259 closeTimeout = setTimeout(function () {
2260 if (tempStyle) {
2261 text.style.cssText = tempStyle;
2262 tempStyle = '';
2263 }
2264 if (host.renderer.$keepTextAreaAtCursor == null) {
2265 host.renderer.$keepTextAreaAtCursor = true;
2266 host.renderer.$moveTextAreaToCursor();
2267 }
2268 }, 0);
2269 }
2270
2271 var onContextMenu = function(e) {
2272 host.textInput.onContextMenu(e);
2273 onContextMenuClose();
2274 };
2275 event.addListener(text, "mouseup", onContextMenu);
2276 event.addListener(text, "mousedown", function(e) {
2277 e.preventDefault();
2278 onContextMenuClose();
2279 });
2280 event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
2281 event.addListener(text, "contextmenu", onContextMenu);
2282
2283 if (useragent.isIOS) {
2284 var typingResetTimeout = null;
2285 var typing = false;
2286
2287 parentNode.addEventListener("keydown", function (e) {
2288 if (typingResetTimeout) clearTimeout(typingResetTimeout);
2289 typing = true;
2290 });
2291
2292 parentNode.addEventListener("keyup", function (e) {
2293 typingResetTimeout = setTimeout(function () {
2294 typing = false;
2295 }, 100);
2296 });
2297 var detectArrowKeys = function(e) {
2298 if (document.activeElement !== text) return;
2299 if (typing) return;
2300
2301 if (cut) {
2302 return setTimeout(function () {
2303 cut = false;
2304 }, 100);
2305 }
2306 var selectionStart = text.selectionStart;
2307 var selectionEnd = text.selectionEnd;
2308 text.setSelectionRange(4, 5);
2309 if (selectionStart == selectionEnd) {
2310 switch (selectionStart) {
2311 case 0: host.onCommandKey(null, 0, KEYS.up); break;
2312 case 1: host.onCommandKey(null, 0, KEYS.home); break;
2313 case 2: host.onCommandKey(null, MODS.option, KEYS.left); break;
2314 case 4: host.onCommandKey(null, 0, KEYS.left); break;
2315 case 5: host.onCommandKey(null, 0, KEYS.right); break;
2316 case 7: host.onCommandKey(null, MODS.option, KEYS.right); break;
2317 case 8: host.onCommandKey(null, 0, KEYS.end); break;
2318 case 9: host.onCommandKey(null, 0, KEYS.down); break;
2319 }
2320 } else {
2321 switch (selectionEnd) {
2322 case 6: host.onCommandKey(null, MODS.shift, KEYS.right); break;
2323 case 7: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.right); break;
2324 case 8: host.onCommandKey(null, MODS.shift, KEYS.end); break;
2325 case 9: host.onCommandKey(null, MODS.shift, KEYS.down); break;
2326 }
2327 switch (selectionStart) {
2328 case 0: host.onCommandKey(null, MODS.shift, KEYS.up); break;
2329 case 1: host.onCommandKey(null, MODS.shift, KEYS.home); break;
2330 case 2: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.left); break;
2331 case 3: host.onCommandKey(null, MODS.shift, KEYS.left); break;
2332 }
2333 }
2334 };
2335 document.addEventListener("selectionchange", detectArrowKeys);
2336 host.on("destroy", function() {
2337 document.removeEventListener("selectionchange", detectArrowKeys);
2338 });
2339 }
2340};
2341
2342exports.TextInput = TextInput;
2343});
2344
2345ace.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) {
2346
2347var event = acequire("../lib/event");
2348var useragent = acequire("../lib/useragent");
2349var dom = acequire("../lib/dom");
2350var lang = acequire("../lib/lang");
2351var BROKEN_SETDATA = useragent.isChrome < 18;
2352var USE_IE_MIME_TYPE = useragent.isIE;
2353
2354var TextInputIOS = acequire("./textinput_ios").TextInput;
2355var TextInput = function(parentNode, host) {
2356 if (useragent.isIOS)
2357 return TextInputIOS.call(this, parentNode, host);
2358
2359 var text = dom.createElement("textarea");
2360 text.className = "ace_text-input";
2361
2362 text.setAttribute("wrap", "off");
2363 text.setAttribute("autocorrect", "off");
2364 text.setAttribute("autocapitalize", "off");
2365 text.setAttribute("spellcheck", false);
2366
2367 text.style.opacity = "0";
2368 parentNode.insertBefore(text, parentNode.firstChild);
2369
2370 var PLACEHOLDER = "\u2028\u2028";
2371
2372 var copied = false;
2373 var pasted = false;
2374 var inComposition = false;
2375 var tempStyle = '';
2376 var isSelectionEmpty = true;
2377 try { var isFocused = document.activeElement === text; } catch(e) {}
2378
2379 event.addListener(text, "blur", function(e) {
2380 host.onBlur(e);
2381 isFocused = false;
2382 });
2383 event.addListener(text, "focus", function(e) {
2384 isFocused = true;
2385 host.onFocus(e);
2386 resetSelection();
2387 });
2388 this.focus = function() {
2389 if (tempStyle) return text.focus();
2390 var top = text.style.top;
2391 text.style.position = "fixed";
2392 text.style.top = "0px";
2393 text.focus();
2394 setTimeout(function() {
2395 text.style.position = "";
2396 if (text.style.top == "0px")
2397 text.style.top = top;
2398 }, 0);
2399 };
2400 this.blur = function() {
2401 text.blur();
2402 };
2403 this.isFocused = function() {
2404 return isFocused;
2405 };
2406 var syncSelection = lang.delayedCall(function() {
2407 isFocused && resetSelection(isSelectionEmpty);
2408 });
2409 var syncValue = lang.delayedCall(function() {
2410 if (!inComposition) {
2411 text.value = PLACEHOLDER;
2412 isFocused && resetSelection();
2413 }
2414 });
2415
2416 function resetSelection(isEmpty) {
2417 if (inComposition)
2418 return;
2419 inComposition = true;
2420
2421 if (inputHandler) {
2422 var selectionStart = 0;
2423 var selectionEnd = isEmpty ? 0 : text.value.length - 1;
2424 } else {
2425 var selectionStart = isEmpty ? 2 : 1;
2426 var selectionEnd = 2;
2427 }
2428 try {
2429 text.setSelectionRange(selectionStart, selectionEnd);
2430 } catch(e){}
2431
2432 inComposition = false;
2433 }
2434
2435 function resetValue() {
2436 if (inComposition)
2437 return;
2438 text.value = PLACEHOLDER;
2439 if (useragent.isWebKit)
2440 syncValue.schedule();
2441 }
2442
2443 useragent.isWebKit || host.addEventListener('changeSelection', function() {
2444 if (host.selection.isEmpty() != isSelectionEmpty) {
2445 isSelectionEmpty = !isSelectionEmpty;
2446 syncSelection.schedule();
2447 }
2448 });
2449
2450 resetValue();
2451 if (isFocused)
2452 host.onFocus();
2453
2454
2455 var isAllSelected = function(text) {
2456 return text.selectionStart === 0 && text.selectionEnd === text.value.length;
2457 };
2458
2459 var onSelect = function(e) {
2460 if (copied) {
2461 copied = false;
2462 } else if (isAllSelected(text)) {
2463 host.selectAll();
2464 resetSelection();
2465 } else if (inputHandler) {
2466 resetSelection(host.selection.isEmpty());
2467 }
2468 };
2469
2470 var inputHandler = null;
2471 this.setInputHandler = function(cb) {inputHandler = cb;};
2472 this.getInputHandler = function() {return inputHandler;};
2473 var afterContextMenu = false;
2474
2475 var sendText = function(data) {
2476 if (inputHandler) {
2477 data = inputHandler(data);
2478 inputHandler = null;
2479 }
2480 if (pasted) {
2481 resetSelection();
2482 if (data)
2483 host.onPaste(data);
2484 pasted = false;
2485 } else if (data == PLACEHOLDER.charAt(0)) {
2486 if (afterContextMenu)
2487 host.execCommand("del", {source: "ace"});
2488 else // some versions of android do not fire keydown when pressing backspace
2489 host.execCommand("backspace", {source: "ace"});
2490 } else {
2491 if (data.substring(0, 2) == PLACEHOLDER)
2492 data = data.substr(2);
2493 else if (data.charAt(0) == PLACEHOLDER.charAt(0))
2494 data = data.substr(1);
2495 else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2496 data = data.slice(0, -1);
2497 if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2498 data = data.slice(0, -1);
2499
2500 if (data)
2501 host.onTextInput(data);
2502 }
2503 if (afterContextMenu)
2504 afterContextMenu = false;
2505 };
2506 var onInput = function(e) {
2507 if (inComposition)
2508 return;
2509 var data = text.value;
2510 sendText(data);
2511 resetValue();
2512 };
2513
2514 var handleClipboardData = function(e, data, forceIEMime) {
2515 var clipboardData = e.clipboardData || window.clipboardData;
2516 if (!clipboardData || BROKEN_SETDATA)
2517 return;
2518 var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain";
2519 try {
2520 if (data) {
2521 return clipboardData.setData(mime, data) !== false;
2522 } else {
2523 return clipboardData.getData(mime);
2524 }
2525 } catch(e) {
2526 if (!forceIEMime)
2527 return handleClipboardData(e, data, true);
2528 }
2529 };
2530
2531 var doCopy = function(e, isCut) {
2532 var data = host.getCopyText();
2533 if (!data)
2534 return event.preventDefault(e);
2535
2536 if (handleClipboardData(e, data)) {
2537 isCut ? host.onCut() : host.onCopy();
2538 event.preventDefault(e);
2539 } else {
2540 copied = true;
2541 text.value = data;
2542 text.select();
2543 setTimeout(function(){
2544 copied = false;
2545 resetValue();
2546 resetSelection();
2547 isCut ? host.onCut() : host.onCopy();
2548 });
2549 }
2550 };
2551
2552 var onCut = function(e) {
2553 doCopy(e, true);
2554 };
2555
2556 var onCopy = function(e) {
2557 doCopy(e, false);
2558 };
2559
2560 var onPaste = function(e) {
2561 var data = handleClipboardData(e);
2562 if (typeof data == "string") {
2563 if (data)
2564 host.onPaste(data, e);
2565 if (useragent.isIE)
2566 setTimeout(resetSelection);
2567 event.preventDefault(e);
2568 }
2569 else {
2570 text.value = "";
2571 pasted = true;
2572 }
2573 };
2574
2575 event.addCommandKeyListener(text, host.onCommandKey.bind(host));
2576
2577 event.addListener(text, "select", onSelect);
2578
2579 event.addListener(text, "input", onInput);
2580
2581 event.addListener(text, "cut", onCut);
2582 event.addListener(text, "copy", onCopy);
2583 event.addListener(text, "paste", onPaste);
2584 if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) {
2585 event.addListener(parentNode, "keydown", function(e) {
2586 if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
2587 return;
2588
2589 switch (e.keyCode) {
2590 case 67:
2591 onCopy(e);
2592 break;
2593 case 86:
2594 onPaste(e);
2595 break;
2596 case 88:
2597 onCut(e);
2598 break;
2599 }
2600 });
2601 }
2602 var onCompositionStart = function(e) {
2603 if (inComposition || !host.onCompositionStart || host.$readOnly)
2604 return;
2605 inComposition = {};
2606 inComposition.canUndo = host.session.$undoManager;
2607 host.onCompositionStart();
2608 setTimeout(onCompositionUpdate, 0);
2609 host.on("mousedown", onCompositionEnd);
2610 if (inComposition.canUndo && !host.selection.isEmpty()) {
2611 host.insert("");
2612 host.session.markUndoGroup();
2613 host.selection.clearSelection();
2614 }
2615 host.session.markUndoGroup();
2616 };
2617
2618 var onCompositionUpdate = function() {
2619 if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
2620 return;
2621 var val = text.value.replace(/\u2028/g, "");
2622 if (inComposition.lastValue === val) return;
2623
2624 host.onCompositionUpdate(val);
2625 if (inComposition.lastValue)
2626 host.undo();
2627 if (inComposition.canUndo)
2628 inComposition.lastValue = val;
2629 if (inComposition.lastValue) {
2630 var r = host.selection.getRange();
2631 host.insert(inComposition.lastValue);
2632 host.session.markUndoGroup();
2633 inComposition.range = host.selection.getRange();
2634 host.selection.setRange(r);
2635 host.selection.clearSelection();
2636 }
2637 };
2638
2639 var onCompositionEnd = function(e) {
2640 if (!host.onCompositionEnd || host.$readOnly) return;
2641 var c = inComposition;
2642 inComposition = false;
2643 var timer = setTimeout(function() {
2644 timer = null;
2645 var str = text.value.replace(/\u2028/g, "");
2646 if (inComposition)
2647 return;
2648 else if (str == c.lastValue)
2649 resetValue();
2650 else if (!c.lastValue && str) {
2651 resetValue();
2652 sendText(str);
2653 }
2654 });
2655 inputHandler = function compositionInputHandler(str) {
2656 if (timer)
2657 clearTimeout(timer);
2658 str = str.replace(/\u2028/g, "");
2659 if (str == c.lastValue)
2660 return "";
2661 if (c.lastValue && timer)
2662 host.undo();
2663 return str;
2664 };
2665 host.onCompositionEnd();
2666 host.removeListener("mousedown", onCompositionEnd);
2667 if (e.type == "compositionend" && c.range) {
2668 host.selection.setRange(c.range);
2669 }
2670 var needsOnInput =
2671 (!!useragent.isChrome && useragent.isChrome >= 53) ||
2672 (!!useragent.isWebKit && useragent.isWebKit >= 603);
2673
2674 if (needsOnInput) {
2675 onInput();
2676 }
2677 };
2678
2679
2680
2681 var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
2682
2683 event.addListener(text, "compositionstart", onCompositionStart);
2684 if (useragent.isGecko) {
2685 event.addListener(text, "text", function(){syncComposition.schedule();});
2686 } else {
2687 event.addListener(text, "keyup", function(){syncComposition.schedule();});
2688 event.addListener(text, "keydown", function(){syncComposition.schedule();});
2689 }
2690 event.addListener(text, "compositionend", onCompositionEnd);
2691
2692 this.getElement = function() {
2693 return text;
2694 };
2695
2696 this.setReadOnly = function(readOnly) {
2697 text.readOnly = readOnly;
2698 };
2699
2700 this.onContextMenu = function(e) {
2701 afterContextMenu = true;
2702 resetSelection(host.selection.isEmpty());
2703 host._emit("nativecontextmenu", {target: host, domEvent: e});
2704 this.moveToMouse(e, true);
2705 };
2706
2707 this.moveToMouse = function(e, bringToFront) {
2708 if (!tempStyle)
2709 tempStyle = text.style.cssText;
2710 text.style.cssText = (bringToFront ? "z-index:100000;" : "")
2711 + "height:" + text.style.height + ";"
2712 + (useragent.isIE ? "opacity:0.1;" : "");
2713
2714 var rect = host.container.getBoundingClientRect();
2715 var style = dom.computedStyle(host.container);
2716 var top = rect.top + (parseInt(style.borderTopWidth) || 0);
2717 var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
2718 var maxTop = rect.bottom - top - text.clientHeight -2;
2719 var move = function(e) {
2720 text.style.left = e.clientX - left - 2 + "px";
2721 text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
2722 };
2723 move(e);
2724
2725 if (e.type != "mousedown")
2726 return;
2727
2728 if (host.renderer.$keepTextAreaAtCursor)
2729 host.renderer.$keepTextAreaAtCursor = null;
2730
2731 clearTimeout(closeTimeout);
2732 if (useragent.isWin)
2733 event.capture(host.container, move, onContextMenuClose);
2734 };
2735
2736 this.onContextMenuClose = onContextMenuClose;
2737 var closeTimeout;
2738 function onContextMenuClose() {
2739 clearTimeout(closeTimeout);
2740 closeTimeout = setTimeout(function () {
2741 if (tempStyle) {
2742 text.style.cssText = tempStyle;
2743 tempStyle = '';
2744 }
2745 if (host.renderer.$keepTextAreaAtCursor == null) {
2746 host.renderer.$keepTextAreaAtCursor = true;
2747 host.renderer.$moveTextAreaToCursor();
2748 }
2749 }, 0);
2750 }
2751
2752 var onContextMenu = function(e) {
2753 host.textInput.onContextMenu(e);
2754 onContextMenuClose();
2755 };
2756 event.addListener(text, "mouseup", onContextMenu);
2757 event.addListener(text, "mousedown", function(e) {
2758 e.preventDefault();
2759 onContextMenuClose();
2760 });
2761 event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
2762 event.addListener(text, "contextmenu", onContextMenu);
2763};
2764
2765exports.TextInput = TextInput;
2766});
2767
2768ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
2769
2770acequire("../lib/dom");
2771acequire("../lib/event");
2772var useragent = acequire("../lib/useragent");
2773
2774var DRAG_OFFSET = 0; // pixels
2775var SCROLL_COOLDOWN_T = 250; // milliseconds
2776
2777function DefaultHandlers(mouseHandler) {
2778 mouseHandler.$clickSelection = null;
2779
2780 var editor = mouseHandler.editor;
2781 editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
2782 editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
2783 editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
2784 editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
2785 editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
2786 editor.setDefaultHandler("touchmove", this.onTouchMove.bind(mouseHandler));
2787
2788 var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd",
2789 "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"];
2790
2791 exports.forEach(function(x) {
2792 mouseHandler[x] = this[x];
2793 }, this);
2794
2795 mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
2796 mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
2797}
2798
2799(function() {
2800
2801 this.onMouseDown = function(ev) {
2802 var inSelection = ev.inSelection();
2803 var pos = ev.getDocumentPosition();
2804 this.mousedownEvent = ev;
2805 var editor = this.editor;
2806
2807 var button = ev.getButton();
2808 if (button !== 0) {
2809 var selectionRange = editor.getSelectionRange();
2810 var selectionEmpty = selectionRange.isEmpty();
2811 editor.$blockScrolling++;
2812 if (selectionEmpty || button == 1)
2813 editor.selection.moveToPosition(pos);
2814 editor.$blockScrolling--;
2815 if (button == 2) {
2816 editor.textInput.onContextMenu(ev.domEvent);
2817 if (!useragent.isMozilla)
2818 ev.preventDefault();
2819 }
2820 return;
2821 }
2822
2823 this.mousedownEvent.time = Date.now();
2824 if (inSelection && !editor.isFocused()) {
2825 editor.focus();
2826 if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
2827 this.setState("focusWait");
2828 this.captureMouse(ev);
2829 return;
2830 }
2831 }
2832
2833 this.captureMouse(ev);
2834 this.startSelect(pos, ev.domEvent._clicks > 1);
2835 return ev.preventDefault();
2836 };
2837
2838 this.startSelect = function(pos, waitForClickSelection) {
2839 pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
2840 var editor = this.editor;
2841 editor.$blockScrolling++;
2842 if (this.mousedownEvent.getShiftKey())
2843 editor.selection.selectToPosition(pos);
2844 else if (!waitForClickSelection)
2845 editor.selection.moveToPosition(pos);
2846 if (!waitForClickSelection)
2847 this.select();
2848 if (editor.renderer.scroller.setCapture) {
2849 editor.renderer.scroller.setCapture();
2850 }
2851 editor.setStyle("ace_selecting");
2852 this.setState("select");
2853 editor.$blockScrolling--;
2854 };
2855
2856 this.select = function() {
2857 var anchor, editor = this.editor;
2858 var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
2859 editor.$blockScrolling++;
2860 if (this.$clickSelection) {
2861 var cmp = this.$clickSelection.comparePoint(cursor);
2862
2863 if (cmp == -1) {
2864 anchor = this.$clickSelection.end;
2865 } else if (cmp == 1) {
2866 anchor = this.$clickSelection.start;
2867 } else {
2868 var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
2869 cursor = orientedRange.cursor;
2870 anchor = orientedRange.anchor;
2871 }
2872 editor.selection.setSelectionAnchor(anchor.row, anchor.column);
2873 }
2874 editor.selection.selectToPosition(cursor);
2875 editor.$blockScrolling--;
2876 editor.renderer.scrollCursorIntoView();
2877 };
2878
2879 this.extendSelectionBy = function(unitName) {
2880 var anchor, editor = this.editor;
2881 var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
2882 var range = editor.selection[unitName](cursor.row, cursor.column);
2883 editor.$blockScrolling++;
2884 if (this.$clickSelection) {
2885 var cmpStart = this.$clickSelection.comparePoint(range.start);
2886 var cmpEnd = this.$clickSelection.comparePoint(range.end);
2887
2888 if (cmpStart == -1 && cmpEnd <= 0) {
2889 anchor = this.$clickSelection.end;
2890 if (range.end.row != cursor.row || range.end.column != cursor.column)
2891 cursor = range.start;
2892 } else if (cmpEnd == 1 && cmpStart >= 0) {
2893 anchor = this.$clickSelection.start;
2894 if (range.start.row != cursor.row || range.start.column != cursor.column)
2895 cursor = range.end;
2896 } else if (cmpStart == -1 && cmpEnd == 1) {
2897 cursor = range.end;
2898 anchor = range.start;
2899 } else {
2900 var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
2901 cursor = orientedRange.cursor;
2902 anchor = orientedRange.anchor;
2903 }
2904 editor.selection.setSelectionAnchor(anchor.row, anchor.column);
2905 }
2906 editor.selection.selectToPosition(cursor);
2907 editor.$blockScrolling--;
2908 editor.renderer.scrollCursorIntoView();
2909 };
2910
2911 this.selectEnd =
2912 this.selectAllEnd =
2913 this.selectByWordsEnd =
2914 this.selectByLinesEnd = function() {
2915 this.$clickSelection = null;
2916 this.editor.unsetStyle("ace_selecting");
2917 if (this.editor.renderer.scroller.releaseCapture) {
2918 this.editor.renderer.scroller.releaseCapture();
2919 }
2920 };
2921
2922 this.focusWait = function() {
2923 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
2924 var time = Date.now();
2925
2926 if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
2927 this.startSelect(this.mousedownEvent.getDocumentPosition());
2928 };
2929
2930 this.onDoubleClick = function(ev) {
2931 var pos = ev.getDocumentPosition();
2932 var editor = this.editor;
2933 var session = editor.session;
2934
2935 var range = session.getBracketRange(pos);
2936 if (range) {
2937 if (range.isEmpty()) {
2938 range.start.column--;
2939 range.end.column++;
2940 }
2941 this.setState("select");
2942 } else {
2943 range = editor.selection.getWordRange(pos.row, pos.column);
2944 this.setState("selectByWords");
2945 }
2946 this.$clickSelection = range;
2947 this.select();
2948 };
2949
2950 this.onTripleClick = function(ev) {
2951 var pos = ev.getDocumentPosition();
2952 var editor = this.editor;
2953
2954 this.setState("selectByLines");
2955 var range = editor.getSelectionRange();
2956 if (range.isMultiLine() && range.contains(pos.row, pos.column)) {
2957 this.$clickSelection = editor.selection.getLineRange(range.start.row);
2958 this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;
2959 } else {
2960 this.$clickSelection = editor.selection.getLineRange(pos.row);
2961 }
2962 this.select();
2963 };
2964
2965 this.onQuadClick = function(ev) {
2966 var editor = this.editor;
2967
2968 editor.selectAll();
2969 this.$clickSelection = editor.getSelectionRange();
2970 this.setState("selectAll");
2971 };
2972
2973 this.onMouseWheel = function(ev) {
2974 if (ev.getAccelKey())
2975 return;
2976 if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {
2977 ev.wheelX = ev.wheelY;
2978 ev.wheelY = 0;
2979 }
2980
2981 var editor = this.editor;
2982
2983 if (!this.$lastScroll)
2984 this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 };
2985
2986 var prevScroll = this.$lastScroll;
2987 var t = ev.domEvent.timeStamp;
2988 var dt = t - prevScroll.t;
2989 var vx = ev.wheelX / dt;
2990 var vy = ev.wheelY / dt;
2991 if (dt < SCROLL_COOLDOWN_T) {
2992 vx = (vx + prevScroll.vx) / 2;
2993 vy = (vy + prevScroll.vy) / 2;
2994 }
2995
2996 var direction = Math.abs(vx / vy);
2997
2998 var canScroll = false;
2999 if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0))
3000 canScroll = true;
3001 if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed))
3002 canScroll = true;
3003
3004 if (canScroll) {
3005 prevScroll.allowed = t;
3006 } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) {
3007 var isSlower = Math.abs(vx) <= 1.1 * Math.abs(prevScroll.vx)
3008 && Math.abs(vy) <= 1.1 * Math.abs(prevScroll.vy);
3009 if (isSlower) {
3010 canScroll = true;
3011 prevScroll.allowed = t;
3012 }
3013 else {
3014 prevScroll.allowed = 0;
3015 }
3016 }
3017
3018 prevScroll.t = t;
3019 prevScroll.vx = vx;
3020 prevScroll.vy = vy;
3021
3022 if (canScroll) {
3023 editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
3024 return ev.stop();
3025 }
3026 };
3027
3028 this.onTouchMove = function(ev) {
3029 this.editor._emit("mousewheel", ev);
3030 };
3031
3032}).call(DefaultHandlers.prototype);
3033
3034exports.DefaultHandlers = DefaultHandlers;
3035
3036function calcDistance(ax, ay, bx, by) {
3037 return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
3038}
3039
3040function calcRangeOrientation(range, cursor) {
3041 if (range.start.row == range.end.row)
3042 var cmp = 2 * cursor.column - range.start.column - range.end.column;
3043 else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)
3044 var cmp = cursor.column - 4;
3045 else
3046 var cmp = 2 * cursor.row - range.start.row - range.end.row;
3047
3048 if (cmp < 0)
3049 return {cursor: range.start, anchor: range.end};
3050 else
3051 return {cursor: range.end, anchor: range.start};
3052}
3053
3054});
3055
3056ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(acequire, exports, module) {
3057
3058acequire("./lib/oop");
3059var dom = acequire("./lib/dom");
3060function Tooltip (parentNode) {
3061 this.isOpen = false;
3062 this.$element = null;
3063 this.$parentNode = parentNode;
3064}
3065
3066(function() {
3067 this.$init = function() {
3068 this.$element = dom.createElement("div");
3069 this.$element.className = "ace_tooltip";
3070 this.$element.style.display = "none";
3071 this.$parentNode.appendChild(this.$element);
3072 return this.$element;
3073 };
3074 this.getElement = function() {
3075 return this.$element || this.$init();
3076 };
3077 this.setText = function(text) {
3078 dom.setInnerText(this.getElement(), text);
3079 };
3080 this.setHtml = function(html) {
3081 this.getElement().innerHTML = html;
3082 };
3083 this.setPosition = function(x, y) {
3084 this.getElement().style.left = x + "px";
3085 this.getElement().style.top = y + "px";
3086 };
3087 this.setClassName = function(className) {
3088 dom.addCssClass(this.getElement(), className);
3089 };
3090 this.show = function(text, x, y) {
3091 if (text != null)
3092 this.setText(text);
3093 if (x != null && y != null)
3094 this.setPosition(x, y);
3095 if (!this.isOpen) {
3096 this.getElement().style.display = "block";
3097 this.isOpen = true;
3098 }
3099 };
3100
3101 this.hide = function() {
3102 if (this.isOpen) {
3103 this.getElement().style.display = "none";
3104 this.isOpen = false;
3105 }
3106 };
3107 this.getHeight = function() {
3108 return this.getElement().offsetHeight;
3109 };
3110 this.getWidth = function() {
3111 return this.getElement().offsetWidth;
3112 };
3113
3114 this.destroy = function() {
3115 this.isOpen = false;
3116 if (this.$element && this.$element.parentNode) {
3117 this.$element.parentNode.removeChild(this.$element);
3118 }
3119 };
3120
3121}).call(Tooltip.prototype);
3122
3123exports.Tooltip = Tooltip;
3124});
3125
3126ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(acequire, exports, module) {
3127var dom = acequire("../lib/dom");
3128var oop = acequire("../lib/oop");
3129var event = acequire("../lib/event");
3130var Tooltip = acequire("../tooltip").Tooltip;
3131
3132function GutterHandler(mouseHandler) {
3133 var editor = mouseHandler.editor;
3134 var gutter = editor.renderer.$gutterLayer;
3135 var tooltip = new GutterTooltip(editor.container);
3136
3137 mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
3138 if (!editor.isFocused() || e.getButton() != 0)
3139 return;
3140 var gutterRegion = gutter.getRegion(e);
3141
3142 if (gutterRegion == "foldWidgets")
3143 return;
3144
3145 var row = e.getDocumentPosition().row;
3146 var selection = editor.session.selection;
3147
3148 if (e.getShiftKey())
3149 selection.selectTo(row, 0);
3150 else {
3151 if (e.domEvent.detail == 2) {
3152 editor.selectAll();
3153 return e.preventDefault();
3154 }
3155 mouseHandler.$clickSelection = editor.selection.getLineRange(row);
3156 }
3157 mouseHandler.setState("selectByLines");
3158 mouseHandler.captureMouse(e);
3159 return e.preventDefault();
3160 });
3161
3162
3163 var tooltipTimeout, mouseEvent, tooltipAnnotation;
3164
3165 function showTooltip() {
3166 var row = mouseEvent.getDocumentPosition().row;
3167 var annotation = gutter.$annotations[row];
3168 if (!annotation)
3169 return hideTooltip();
3170
3171 var maxRow = editor.session.getLength();
3172 if (row == maxRow) {
3173 var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
3174 var pos = mouseEvent.$pos;
3175 if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
3176 return hideTooltip();
3177 }
3178
3179 if (tooltipAnnotation == annotation)
3180 return;
3181 tooltipAnnotation = annotation.text.join("<br/>");
3182
3183 tooltip.setHtml(tooltipAnnotation);
3184 tooltip.show();
3185 editor._signal("showGutterTooltip", tooltip);
3186 editor.on("mousewheel", hideTooltip);
3187
3188 if (mouseHandler.$tooltipFollowsMouse) {
3189 moveTooltip(mouseEvent);
3190 } else {
3191 var gutterElement = mouseEvent.domEvent.target;
3192 var rect = gutterElement.getBoundingClientRect();
3193 var style = tooltip.getElement().style;
3194 style.left = rect.right + "px";
3195 style.top = rect.bottom + "px";
3196 }
3197 }
3198
3199 function hideTooltip() {
3200 if (tooltipTimeout)
3201 tooltipTimeout = clearTimeout(tooltipTimeout);
3202 if (tooltipAnnotation) {
3203 tooltip.hide();
3204 tooltipAnnotation = null;
3205 editor._signal("hideGutterTooltip", tooltip);
3206 editor.removeEventListener("mousewheel", hideTooltip);
3207 }
3208 }
3209
3210 function moveTooltip(e) {
3211 tooltip.setPosition(e.x, e.y);
3212 }
3213
3214 mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
3215 var target = e.domEvent.target || e.domEvent.srcElement;
3216 if (dom.hasCssClass(target, "ace_fold-widget"))
3217 return hideTooltip();
3218
3219 if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)
3220 moveTooltip(e);
3221
3222 mouseEvent = e;
3223 if (tooltipTimeout)
3224 return;
3225 tooltipTimeout = setTimeout(function() {
3226 tooltipTimeout = null;
3227 if (mouseEvent && !mouseHandler.isMousePressed)
3228 showTooltip();
3229 else
3230 hideTooltip();
3231 }, 50);
3232 });
3233
3234 event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
3235 mouseEvent = null;
3236 if (!tooltipAnnotation || tooltipTimeout)
3237 return;
3238
3239 tooltipTimeout = setTimeout(function() {
3240 tooltipTimeout = null;
3241 hideTooltip();
3242 }, 50);
3243 });
3244
3245 editor.on("changeSession", hideTooltip);
3246}
3247
3248function GutterTooltip(parentNode) {
3249 Tooltip.call(this, parentNode);
3250}
3251
3252oop.inherits(GutterTooltip, Tooltip);
3253
3254(function(){
3255 this.setPosition = function(x, y) {
3256 var windowWidth = window.innerWidth || document.documentElement.clientWidth;
3257 var windowHeight = window.innerHeight || document.documentElement.clientHeight;
3258 var width = this.getWidth();
3259 var height = this.getHeight();
3260 x += 15;
3261 y += 15;
3262 if (x + width > windowWidth) {
3263 x -= (x + width) - windowWidth;
3264 }
3265 if (y + height > windowHeight) {
3266 y -= 20 + height;
3267 }
3268 Tooltip.prototype.setPosition.call(this, x, y);
3269 };
3270
3271}).call(GutterTooltip.prototype);
3272
3273
3274
3275exports.GutterHandler = GutterHandler;
3276
3277});
3278
3279ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
3280
3281var event = acequire("../lib/event");
3282var useragent = acequire("../lib/useragent");
3283var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
3284 this.domEvent = domEvent;
3285 this.editor = editor;
3286
3287 this.x = this.clientX = domEvent.clientX;
3288 this.y = this.clientY = domEvent.clientY;
3289
3290 this.$pos = null;
3291 this.$inSelection = null;
3292
3293 this.propagationStopped = false;
3294 this.defaultPrevented = false;
3295};
3296
3297(function() {
3298
3299 this.stopPropagation = function() {
3300 event.stopPropagation(this.domEvent);
3301 this.propagationStopped = true;
3302 };
3303
3304 this.preventDefault = function() {
3305 event.preventDefault(this.domEvent);
3306 this.defaultPrevented = true;
3307 };
3308
3309 this.stop = function() {
3310 this.stopPropagation();
3311 this.preventDefault();
3312 };
3313 this.getDocumentPosition = function() {
3314 if (this.$pos)
3315 return this.$pos;
3316
3317 this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
3318 return this.$pos;
3319 };
3320 this.inSelection = function() {
3321 if (this.$inSelection !== null)
3322 return this.$inSelection;
3323
3324 var editor = this.editor;
3325
3326
3327 var selectionRange = editor.getSelectionRange();
3328 if (selectionRange.isEmpty())
3329 this.$inSelection = false;
3330 else {
3331 var pos = this.getDocumentPosition();
3332 this.$inSelection = selectionRange.contains(pos.row, pos.column);
3333 }
3334
3335 return this.$inSelection;
3336 };
3337 this.getButton = function() {
3338 return event.getButton(this.domEvent);
3339 };
3340 this.getShiftKey = function() {
3341 return this.domEvent.shiftKey;
3342 };
3343
3344 this.getAccelKey = useragent.isMac
3345 ? function() { return this.domEvent.metaKey; }
3346 : function() { return this.domEvent.ctrlKey; };
3347
3348}).call(MouseEvent.prototype);
3349
3350});
3351
3352ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
3353
3354var dom = acequire("../lib/dom");
3355var event = acequire("../lib/event");
3356var useragent = acequire("../lib/useragent");
3357
3358var AUTOSCROLL_DELAY = 200;
3359var SCROLL_CURSOR_DELAY = 200;
3360var SCROLL_CURSOR_HYSTERESIS = 5;
3361
3362function DragdropHandler(mouseHandler) {
3363
3364 var editor = mouseHandler.editor;
3365
3366 var blankImage = dom.createElement("img");
3367 blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
3368 if (useragent.isOpera)
3369 blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;";
3370
3371 var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"];
3372
3373 exports.forEach(function(x) {
3374 mouseHandler[x] = this[x];
3375 }, this);
3376 editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler));
3377
3378
3379 var mouseTarget = editor.container;
3380 var dragSelectionMarker, x, y;
3381 var timerId, range;
3382 var dragCursor, counter = 0;
3383 var dragOperation;
3384 var isInternal;
3385 var autoScrollStartTime;
3386 var cursorMovedTime;
3387 var cursorPointOnCaretMoved;
3388
3389 this.onDragStart = function(e) {
3390 if (this.cancelDrag || !mouseTarget.draggable) {
3391 var self = this;
3392 setTimeout(function(){
3393 self.startSelect();
3394 self.captureMouse(e);
3395 }, 0);
3396 return e.preventDefault();
3397 }
3398 range = editor.getSelectionRange();
3399
3400 var dataTransfer = e.dataTransfer;
3401 dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove";
3402 if (useragent.isOpera) {
3403 editor.container.appendChild(blankImage);
3404 blankImage.scrollTop = 0;
3405 }
3406 dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0);
3407 if (useragent.isOpera) {
3408 editor.container.removeChild(blankImage);
3409 }
3410 dataTransfer.clearData();
3411 dataTransfer.setData("Text", editor.session.getTextRange());
3412
3413 isInternal = true;
3414 this.setState("drag");
3415 };
3416
3417 this.onDragEnd = function(e) {
3418 mouseTarget.draggable = false;
3419 isInternal = false;
3420 this.setState(null);
3421 if (!editor.getReadOnly()) {
3422 var dropEffect = e.dataTransfer.dropEffect;
3423 if (!dragOperation && dropEffect == "move")
3424 editor.session.remove(editor.getSelectionRange());
3425 editor.renderer.$cursorLayer.setBlinking(true);
3426 }
3427 this.editor.unsetStyle("ace_dragging");
3428 this.editor.renderer.setCursorStyle("");
3429 };
3430
3431 this.onDragEnter = function(e) {
3432 if (editor.getReadOnly() || !canAccept(e.dataTransfer))
3433 return;
3434 x = e.clientX;
3435 y = e.clientY;
3436 if (!dragSelectionMarker)
3437 addDragMarker();
3438 counter++;
3439 e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
3440 return event.preventDefault(e);
3441 };
3442
3443 this.onDragOver = function(e) {
3444 if (editor.getReadOnly() || !canAccept(e.dataTransfer))
3445 return;
3446 x = e.clientX;
3447 y = e.clientY;
3448 if (!dragSelectionMarker) {
3449 addDragMarker();
3450 counter++;
3451 }
3452 if (onMouseMoveTimer !== null)
3453 onMouseMoveTimer = null;
3454
3455 e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
3456 return event.preventDefault(e);
3457 };
3458
3459 this.onDragLeave = function(e) {
3460 counter--;
3461 if (counter <= 0 && dragSelectionMarker) {
3462 clearDragMarker();
3463 dragOperation = null;
3464 return event.preventDefault(e);
3465 }
3466 };
3467
3468 this.onDrop = function(e) {
3469 if (!dragCursor)
3470 return;
3471 var dataTransfer = e.dataTransfer;
3472 if (isInternal) {
3473 switch (dragOperation) {
3474 case "move":
3475 if (range.contains(dragCursor.row, dragCursor.column)) {
3476 range = {
3477 start: dragCursor,
3478 end: dragCursor
3479 };
3480 } else {
3481 range = editor.moveText(range, dragCursor);
3482 }
3483 break;
3484 case "copy":
3485 range = editor.moveText(range, dragCursor, true);
3486 break;
3487 }
3488 } else {
3489 var dropData = dataTransfer.getData('Text');
3490 range = {
3491 start: dragCursor,
3492 end: editor.session.insert(dragCursor, dropData)
3493 };
3494 editor.focus();
3495 dragOperation = null;
3496 }
3497 clearDragMarker();
3498 return event.preventDefault(e);
3499 };
3500
3501 event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler));
3502 event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler));
3503 event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler));
3504 event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler));
3505 event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler));
3506 event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler));
3507
3508 function scrollCursorIntoView(cursor, prevCursor) {
3509 var now = Date.now();
3510 var vMovement = !prevCursor || cursor.row != prevCursor.row;
3511 var hMovement = !prevCursor || cursor.column != prevCursor.column;
3512 if (!cursorMovedTime || vMovement || hMovement) {
3513 editor.$blockScrolling += 1;
3514 editor.moveCursorToPosition(cursor);
3515 editor.$blockScrolling -= 1;
3516 cursorMovedTime = now;
3517 cursorPointOnCaretMoved = {x: x, y: y};
3518 } else {
3519 var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y);
3520 if (distance > SCROLL_CURSOR_HYSTERESIS) {
3521 cursorMovedTime = null;
3522 } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) {
3523 editor.renderer.scrollCursorIntoView();
3524 cursorMovedTime = null;
3525 }
3526 }
3527 }
3528
3529 function autoScroll(cursor, prevCursor) {
3530 var now = Date.now();
3531 var lineHeight = editor.renderer.layerConfig.lineHeight;
3532 var characterWidth = editor.renderer.layerConfig.characterWidth;
3533 var editorRect = editor.renderer.scroller.getBoundingClientRect();
3534 var offsets = {
3535 x: {
3536 left: x - editorRect.left,
3537 right: editorRect.right - x
3538 },
3539 y: {
3540 top: y - editorRect.top,
3541 bottom: editorRect.bottom - y
3542 }
3543 };
3544 var nearestXOffset = Math.min(offsets.x.left, offsets.x.right);
3545 var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom);
3546 var scrollCursor = {row: cursor.row, column: cursor.column};
3547 if (nearestXOffset / characterWidth <= 2) {
3548 scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2);
3549 }
3550 if (nearestYOffset / lineHeight <= 1) {
3551 scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1);
3552 }
3553 var vScroll = cursor.row != scrollCursor.row;
3554 var hScroll = cursor.column != scrollCursor.column;
3555 var vMovement = !prevCursor || cursor.row != prevCursor.row;
3556 if (vScroll || (hScroll && !vMovement)) {
3557 if (!autoScrollStartTime)
3558 autoScrollStartTime = now;
3559 else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY)
3560 editor.renderer.scrollCursorIntoView(scrollCursor);
3561 } else {
3562 autoScrollStartTime = null;
3563 }
3564 }
3565
3566 function onDragInterval() {
3567 var prevCursor = dragCursor;
3568 dragCursor = editor.renderer.screenToTextCoordinates(x, y);
3569 scrollCursorIntoView(dragCursor, prevCursor);
3570 autoScroll(dragCursor, prevCursor);
3571 }
3572
3573 function addDragMarker() {
3574 range = editor.selection.toOrientedRange();
3575 dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
3576 editor.clearSelection();
3577 if (editor.isFocused())
3578 editor.renderer.$cursorLayer.setBlinking(false);
3579 clearInterval(timerId);
3580 onDragInterval();
3581 timerId = setInterval(onDragInterval, 20);
3582 counter = 0;
3583 event.addListener(document, "mousemove", onMouseMove);
3584 }
3585
3586 function clearDragMarker() {
3587 clearInterval(timerId);
3588 editor.session.removeMarker(dragSelectionMarker);
3589 dragSelectionMarker = null;
3590 editor.$blockScrolling += 1;
3591 editor.selection.fromOrientedRange(range);
3592 editor.$blockScrolling -= 1;
3593 if (editor.isFocused() && !isInternal)
3594 editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly());
3595 range = null;
3596 dragCursor = null;
3597 counter = 0;
3598 autoScrollStartTime = null;
3599 cursorMovedTime = null;
3600 event.removeListener(document, "mousemove", onMouseMove);
3601 }
3602 var onMouseMoveTimer = null;
3603 function onMouseMove() {
3604 if (onMouseMoveTimer == null) {
3605 onMouseMoveTimer = setTimeout(function() {
3606 if (onMouseMoveTimer != null && dragSelectionMarker)
3607 clearDragMarker();
3608 }, 20);
3609 }
3610 }
3611
3612 function canAccept(dataTransfer) {
3613 var types = dataTransfer.types;
3614 return !types || Array.prototype.some.call(types, function(type) {
3615 return type == 'text/plain' || type == 'Text';
3616 });
3617 }
3618
3619 function getDropEffect(e) {
3620 var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];
3621 var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];
3622
3623 var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey;
3624 var effectAllowed = "uninitialized";
3625 try {
3626 effectAllowed = e.dataTransfer.effectAllowed.toLowerCase();
3627 } catch (e) {}
3628 var dropEffect = "none";
3629
3630 if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0)
3631 dropEffect = "copy";
3632 else if (moveAllowed.indexOf(effectAllowed) >= 0)
3633 dropEffect = "move";
3634 else if (copyAllowed.indexOf(effectAllowed) >= 0)
3635 dropEffect = "copy";
3636
3637 return dropEffect;
3638 }
3639}
3640
3641(function() {
3642
3643 this.dragWait = function() {
3644 var interval = Date.now() - this.mousedownEvent.time;
3645 if (interval > this.editor.getDragDelay())
3646 this.startDrag();
3647 };
3648
3649 this.dragWaitEnd = function() {
3650 var target = this.editor.container;
3651 target.draggable = false;
3652 this.startSelect(this.mousedownEvent.getDocumentPosition());
3653 this.selectEnd();
3654 };
3655
3656 this.dragReadyEnd = function(e) {
3657 this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly());
3658 this.editor.unsetStyle("ace_dragging");
3659 this.editor.renderer.setCursorStyle("");
3660 this.dragWaitEnd();
3661 };
3662
3663 this.startDrag = function(){
3664 this.cancelDrag = false;
3665 var editor = this.editor;
3666 var target = editor.container;
3667 target.draggable = true;
3668 editor.renderer.$cursorLayer.setBlinking(false);
3669 editor.setStyle("ace_dragging");
3670 var cursorStyle = useragent.isWin ? "default" : "move";
3671 editor.renderer.setCursorStyle(cursorStyle);
3672 this.setState("dragReady");
3673 };
3674
3675 this.onMouseDrag = function(e) {
3676 var target = this.editor.container;
3677 if (useragent.isIE && this.state == "dragReady") {
3678 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3679 if (distance > 3)
3680 target.dragDrop();
3681 }
3682 if (this.state === "dragWait") {
3683 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3684 if (distance > 0) {
3685 target.draggable = false;
3686 this.startSelect(this.mousedownEvent.getDocumentPosition());
3687 }
3688 }
3689 };
3690
3691 this.onMouseDown = function(e) {
3692 if (!this.$dragEnabled)
3693 return;
3694 this.mousedownEvent = e;
3695 var editor = this.editor;
3696
3697 var inSelection = e.inSelection();
3698 var button = e.getButton();
3699 var clickCount = e.domEvent.detail || 1;
3700 if (clickCount === 1 && button === 0 && inSelection) {
3701 if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey()))
3702 return;
3703 this.mousedownEvent.time = Date.now();
3704 var eventTarget = e.domEvent.target || e.domEvent.srcElement;
3705 if ("unselectable" in eventTarget)
3706 eventTarget.unselectable = "on";
3707 if (editor.getDragDelay()) {
3708 if (useragent.isWebKit) {
3709 this.cancelDrag = true;
3710 var mouseTarget = editor.container;
3711 mouseTarget.draggable = true;
3712 }
3713 this.setState("dragWait");
3714 } else {
3715 this.startDrag();
3716 }
3717 this.captureMouse(e, this.onMouseDrag.bind(this));
3718 e.defaultPrevented = true;
3719 }
3720 };
3721
3722}).call(DragdropHandler.prototype);
3723
3724
3725function calcDistance(ax, ay, bx, by) {
3726 return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
3727}
3728
3729exports.DragdropHandler = DragdropHandler;
3730
3731});
3732
3733ace.define("ace/lib/net",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) {
3734var dom = acequire("./dom");
3735
3736exports.get = function (url, callback) {
3737 var xhr = new XMLHttpRequest();
3738 xhr.open('GET', url, true);
3739 xhr.onreadystatechange = function () {
3740 if (xhr.readyState === 4) {
3741 callback(xhr.responseText);
3742 }
3743 };
3744 xhr.send(null);
3745};
3746
3747exports.loadScript = function(path, callback) {
3748 var head = dom.getDocumentHead();
3749 var s = document.createElement('script');
3750
3751 s.src = path;
3752 head.appendChild(s);
3753
3754 s.onload = s.onreadystatechange = function(_, isAbort) {
3755 if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
3756 s = s.onload = s.onreadystatechange = null;
3757 if (!isAbort)
3758 callback();
3759 }
3760 };
3761};
3762exports.qualifyURL = function(url) {
3763 var a = document.createElement('a');
3764 a.href = url;
3765 return a.href;
3766};
3767
3768});
3769
3770ace.define("ace/lib/event_emitter",["require","exports","module"], function(acequire, exports, module) {
3771
3772var EventEmitter = {};
3773var stopPropagation = function() { this.propagationStopped = true; };
3774var preventDefault = function() { this.defaultPrevented = true; };
3775
3776EventEmitter._emit =
3777EventEmitter._dispatchEvent = function(eventName, e) {
3778 this._eventRegistry || (this._eventRegistry = {});
3779 this._defaultHandlers || (this._defaultHandlers = {});
3780
3781 var listeners = this._eventRegistry[eventName] || [];
3782 var defaultHandler = this._defaultHandlers[eventName];
3783 if (!listeners.length && !defaultHandler)
3784 return;
3785
3786 if (typeof e != "object" || !e)
3787 e = {};
3788
3789 if (!e.type)
3790 e.type = eventName;
3791 if (!e.stopPropagation)
3792 e.stopPropagation = stopPropagation;
3793 if (!e.preventDefault)
3794 e.preventDefault = preventDefault;
3795
3796 listeners = listeners.slice();
3797 for (var i=0; i<listeners.length; i++) {
3798 listeners[i](e, this);
3799 if (e.propagationStopped)
3800 break;
3801 }
3802
3803 if (defaultHandler && !e.defaultPrevented)
3804 return defaultHandler(e, this);
3805};
3806
3807
3808EventEmitter._signal = function(eventName, e) {
3809 var listeners = (this._eventRegistry || {})[eventName];
3810 if (!listeners)
3811 return;
3812 listeners = listeners.slice();
3813 for (var i=0; i<listeners.length; i++)
3814 listeners[i](e, this);
3815};
3816
3817EventEmitter.once = function(eventName, callback) {
3818 var _self = this;
3819 callback && this.addEventListener(eventName, function newCallback() {
3820 _self.removeEventListener(eventName, newCallback);
3821 callback.apply(null, arguments);
3822 });
3823};
3824
3825
3826EventEmitter.setDefaultHandler = function(eventName, callback) {
3827 var handlers = this._defaultHandlers;
3828 if (!handlers)
3829 handlers = this._defaultHandlers = {_disabled_: {}};
3830
3831 if (handlers[eventName]) {
3832 var old = handlers[eventName];
3833 var disabled = handlers._disabled_[eventName];
3834 if (!disabled)
3835 handlers._disabled_[eventName] = disabled = [];
3836 disabled.push(old);
3837 var i = disabled.indexOf(callback);
3838 if (i != -1)
3839 disabled.splice(i, 1);
3840 }
3841 handlers[eventName] = callback;
3842};
3843EventEmitter.removeDefaultHandler = function(eventName, callback) {
3844 var handlers = this._defaultHandlers;
3845 if (!handlers)
3846 return;
3847 var disabled = handlers._disabled_[eventName];
3848
3849 if (handlers[eventName] == callback) {
3850 handlers[eventName];
3851 if (disabled)
3852 this.setDefaultHandler(eventName, disabled.pop());
3853 } else if (disabled) {
3854 var i = disabled.indexOf(callback);
3855 if (i != -1)
3856 disabled.splice(i, 1);
3857 }
3858};
3859
3860EventEmitter.on =
3861EventEmitter.addEventListener = function(eventName, callback, capturing) {
3862 this._eventRegistry = this._eventRegistry || {};
3863
3864 var listeners = this._eventRegistry[eventName];
3865 if (!listeners)
3866 listeners = this._eventRegistry[eventName] = [];
3867
3868 if (listeners.indexOf(callback) == -1)
3869 listeners[capturing ? "unshift" : "push"](callback);
3870 return callback;
3871};
3872
3873EventEmitter.off =
3874EventEmitter.removeListener =
3875EventEmitter.removeEventListener = function(eventName, callback) {
3876 this._eventRegistry = this._eventRegistry || {};
3877
3878 var listeners = this._eventRegistry[eventName];
3879 if (!listeners)
3880 return;
3881
3882 var index = listeners.indexOf(callback);
3883 if (index !== -1)
3884 listeners.splice(index, 1);
3885};
3886
3887EventEmitter.removeAllListeners = function(eventName) {
3888 if (this._eventRegistry) this._eventRegistry[eventName] = [];
3889};
3890
3891exports.EventEmitter = EventEmitter;
3892
3893});
3894
3895ace.define("ace/lib/app_config",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(acequire, exports, module) {
3896"no use strict";
3897
3898var oop = acequire("./oop");
3899var EventEmitter = acequire("./event_emitter").EventEmitter;
3900
3901var optionsProvider = {
3902 setOptions: function(optList) {
3903 Object.keys(optList).forEach(function(key) {
3904 this.setOption(key, optList[key]);
3905 }, this);
3906 },
3907 getOptions: function(optionNames) {
3908 var result = {};
3909 if (!optionNames) {
3910 optionNames = Object.keys(this.$options);
3911 } else if (!Array.isArray(optionNames)) {
3912 result = optionNames;
3913 optionNames = Object.keys(result);
3914 }
3915 optionNames.forEach(function(key) {
3916 result[key] = this.getOption(key);
3917 }, this);
3918 return result;
3919 },
3920 setOption: function(name, value) {
3921 if (this["$" + name] === value)
3922 return;
3923 var opt = this.$options[name];
3924 if (!opt) {
3925 return warn('misspelled option "' + name + '"');
3926 }
3927 if (opt.forwardTo)
3928 return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
3929
3930 if (!opt.handlesSet)
3931 this["$" + name] = value;
3932 if (opt && opt.set)
3933 opt.set.call(this, value);
3934 },
3935 getOption: function(name) {
3936 var opt = this.$options[name];
3937 if (!opt) {
3938 return warn('misspelled option "' + name + '"');
3939 }
3940 if (opt.forwardTo)
3941 return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
3942 return opt && opt.get ? opt.get.call(this) : this["$" + name];
3943 }
3944};
3945
3946function warn(message) {
3947 if (typeof console != "undefined" && console.warn)
3948 console.warn.apply(console, arguments);
3949}
3950
3951function reportError(msg, data) {
3952 var e = new Error(msg);
3953 e.data = data;
3954 if (typeof console == "object" && console.error)
3955 console.error(e);
3956 setTimeout(function() { throw e; });
3957}
3958
3959var AppConfig = function() {
3960 this.$defaultOptions = {};
3961};
3962
3963(function() {
3964 oop.implement(this, EventEmitter);
3965 this.defineOptions = function(obj, path, options) {
3966 if (!obj.$options)
3967 this.$defaultOptions[path] = obj.$options = {};
3968
3969 Object.keys(options).forEach(function(key) {
3970 var opt = options[key];
3971 if (typeof opt == "string")
3972 opt = {forwardTo: opt};
3973
3974 opt.name || (opt.name = key);
3975 obj.$options[opt.name] = opt;
3976 if ("initialValue" in opt)
3977 obj["$" + opt.name] = opt.initialValue;
3978 });
3979 oop.implement(obj, optionsProvider);
3980
3981 return this;
3982 };
3983
3984 this.resetOptions = function(obj) {
3985 Object.keys(obj.$options).forEach(function(key) {
3986 var opt = obj.$options[key];
3987 if ("value" in opt)
3988 obj.setOption(key, opt.value);
3989 });
3990 };
3991
3992 this.setDefaultValue = function(path, name, value) {
3993 var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {});
3994 if (opts[name]) {
3995 if (opts.forwardTo)
3996 this.setDefaultValue(opts.forwardTo, name, value);
3997 else
3998 opts[name].value = value;
3999 }
4000 };
4001
4002 this.setDefaultValues = function(path, optionHash) {
4003 Object.keys(optionHash).forEach(function(key) {
4004 this.setDefaultValue(path, key, optionHash[key]);
4005 }, this);
4006 };
4007
4008 this.warn = warn;
4009 this.reportError = reportError;
4010
4011}).call(AppConfig.prototype);
4012
4013exports.AppConfig = AppConfig;
4014
4015});
4016
4017ace.define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/app_config"], function(acequire, exports, module) {
4018"no use strict";
4019
4020var lang = acequire("./lib/lang");
4021acequire("./lib/oop");
4022var net = acequire("./lib/net");
4023var AppConfig = acequire("./lib/app_config").AppConfig;
4024
4025module.exports = exports = new AppConfig();
4026
4027var global = (function() {
4028 return this || typeof window != "undefined" && window;
4029})();
4030
4031var options = {
4032 packaged: false,
4033 workerPath: null,
4034 modePath: null,
4035 themePath: null,
4036 basePath: "",
4037 suffix: ".js",
4038 $moduleUrls: {}
4039};
4040
4041exports.get = function(key) {
4042 if (!options.hasOwnProperty(key))
4043 throw new Error("Unknown config key: " + key);
4044
4045 return options[key];
4046};
4047
4048exports.set = function(key, value) {
4049 if (!options.hasOwnProperty(key))
4050 throw new Error("Unknown config key: " + key);
4051
4052 options[key] = value;
4053};
4054
4055exports.all = function() {
4056 return lang.copyObject(options);
4057};
4058exports.moduleUrl = function(name, component) {
4059 if (options.$moduleUrls[name])
4060 return options.$moduleUrls[name];
4061
4062 var parts = name.split("/");
4063 component = component || parts[parts.length - 2] || "";
4064 var sep = component == "snippets" ? "/" : "-";
4065 var base = parts[parts.length - 1];
4066 if (component == "worker" && sep == "-") {
4067 var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g");
4068 base = base.replace(re, "");
4069 }
4070
4071 if ((!base || base == component) && parts.length > 1)
4072 base = parts[parts.length - 2];
4073 var path = options[component + "Path"];
4074 if (path == null) {
4075 path = options.basePath;
4076 } else if (sep == "/") {
4077 component = sep = "";
4078 }
4079 if (path && path.slice(-1) != "/")
4080 path += "/";
4081 return path + component + sep + base + this.get("suffix");
4082};
4083
4084exports.setModuleUrl = function(name, subst) {
4085 return options.$moduleUrls[name] = subst;
4086};
4087
4088exports.$loading = {};
4089exports.loadModule = function(moduleName, onLoad) {
4090 var module, moduleType;
4091 if (Array.isArray(moduleName)) {
4092 moduleType = moduleName[0];
4093 moduleName = moduleName[1];
4094 }
4095
4096 try {
4097 module = acequire(moduleName);
4098 } catch (e) {}
4099 if (module && !exports.$loading[moduleName])
4100 return onLoad && onLoad(module);
4101
4102 if (!exports.$loading[moduleName])
4103 exports.$loading[moduleName] = [];
4104
4105 exports.$loading[moduleName].push(onLoad);
4106
4107 if (exports.$loading[moduleName].length > 1)
4108 return;
4109
4110 var afterLoad = function() {
4111 acequire([moduleName], function(module) {
4112 exports._emit("load.module", {name: moduleName, module: module});
4113 var listeners = exports.$loading[moduleName];
4114 exports.$loading[moduleName] = null;
4115 listeners.forEach(function(onLoad) {
4116 onLoad && onLoad(module);
4117 });
4118 });
4119 };
4120
4121 if (!exports.get("packaged"))
4122 return afterLoad();
4123 net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
4124};
4125init(true);function init(packaged) {
4126
4127 if (!global || !global.document)
4128 return;
4129
4130 options.packaged = packaged || acequire.packaged || module.packaged || (global.define && undefined.packaged);
4131
4132 var scriptOptions = {};
4133 var scriptUrl = "";
4134 var currentScript = (document.currentScript || document._currentScript ); // native or polyfill
4135 var currentDocument = currentScript && currentScript.ownerDocument || document;
4136
4137 var scripts = currentDocument.getElementsByTagName("script");
4138 for (var i=0; i<scripts.length; i++) {
4139 var script = scripts[i];
4140
4141 var src = script.src || script.getAttribute("src");
4142 if (!src)
4143 continue;
4144
4145 var attributes = script.attributes;
4146 for (var j=0, l=attributes.length; j < l; j++) {
4147 var attr = attributes[j];
4148 if (attr.name.indexOf("data-ace-") === 0) {
4149 scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
4150 }
4151 }
4152
4153 var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
4154 if (m)
4155 scriptUrl = m[1];
4156 }
4157
4158 if (scriptUrl) {
4159 scriptOptions.base = scriptOptions.base || scriptUrl;
4160 scriptOptions.packaged = true;
4161 }
4162
4163 scriptOptions.basePath = scriptOptions.base;
4164 scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
4165 scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
4166 scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
4167 delete scriptOptions.base;
4168
4169 for (var key in scriptOptions)
4170 if (typeof scriptOptions[key] !== "undefined")
4171 exports.set(key, scriptOptions[key]);
4172}
4173
4174exports.init = init;
4175
4176function deHyphenate(str) {
4177 return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
4178}
4179
4180});
4181
4182ace.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) {
4183
4184var event = acequire("../lib/event");
4185var useragent = acequire("../lib/useragent");
4186var DefaultHandlers = acequire("./default_handlers").DefaultHandlers;
4187var DefaultGutterHandler = acequire("./default_gutter_handler").GutterHandler;
4188var MouseEvent = acequire("./mouse_event").MouseEvent;
4189var DragdropHandler = acequire("./dragdrop_handler").DragdropHandler;
4190var config = acequire("../config");
4191
4192var MouseHandler = function(editor) {
4193 var _self = this;
4194 this.editor = editor;
4195
4196 new DefaultHandlers(this);
4197 new DefaultGutterHandler(this);
4198 new DragdropHandler(this);
4199
4200 var focusEditor = function(e) {
4201 var windowBlurred = !document.hasFocus || !document.hasFocus()
4202 || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement());
4203 if (windowBlurred)
4204 window.focus();
4205 editor.focus();
4206 };
4207
4208 var mouseTarget = editor.renderer.getMouseEventTarget();
4209 event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
4210 event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
4211 event.addMultiMouseDownListener([
4212 mouseTarget,
4213 editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner,
4214 editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner,
4215 editor.textInput && editor.textInput.getElement()
4216 ].filter(Boolean), [400, 300, 250], this, "onMouseEvent");
4217 event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
4218 event.addTouchMoveListener(editor.container, this.onTouchMove.bind(this, "touchmove"));
4219
4220 var gutterEl = editor.renderer.$gutter;
4221 event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
4222 event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
4223 event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
4224 event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
4225
4226 event.addListener(mouseTarget, "mousedown", focusEditor);
4227 event.addListener(gutterEl, "mousedown", focusEditor);
4228 if (useragent.isIE && editor.renderer.scrollBarV) {
4229 event.addListener(editor.renderer.scrollBarV.element, "mousedown", focusEditor);
4230 event.addListener(editor.renderer.scrollBarH.element, "mousedown", focusEditor);
4231 }
4232
4233 editor.on("mousemove", function(e){
4234 if (_self.state || _self.$dragDelay || !_self.$dragEnabled)
4235 return;
4236
4237 var character = editor.renderer.screenToTextCoordinates(e.x, e.y);
4238 var range = editor.session.selection.getRange();
4239 var renderer = editor.renderer;
4240
4241 if (!range.isEmpty() && range.insideStart(character.row, character.column)) {
4242 renderer.setCursorStyle("default");
4243 } else {
4244 renderer.setCursorStyle("");
4245 }
4246 });
4247};
4248
4249(function() {
4250 this.onMouseEvent = function(name, e) {
4251 this.editor._emit(name, new MouseEvent(e, this.editor));
4252 };
4253
4254 this.onMouseMove = function(name, e) {
4255 var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
4256 if (!listeners || !listeners.length)
4257 return;
4258
4259 this.editor._emit(name, new MouseEvent(e, this.editor));
4260 };
4261
4262 this.onMouseWheel = function(name, e) {
4263 var mouseEvent = new MouseEvent(e, this.editor);
4264 mouseEvent.speed = this.$scrollSpeed * 2;
4265 mouseEvent.wheelX = e.wheelX;
4266 mouseEvent.wheelY = e.wheelY;
4267
4268 this.editor._emit(name, mouseEvent);
4269 };
4270
4271 this.onTouchMove = function (name, e) {
4272 var mouseEvent = new MouseEvent(e, this.editor);
4273 mouseEvent.speed = 1;//this.$scrollSpeed * 2;
4274 mouseEvent.wheelX = e.wheelX;
4275 mouseEvent.wheelY = e.wheelY;
4276 this.editor._emit(name, mouseEvent);
4277 };
4278
4279 this.setState = function(state) {
4280 this.state = state;
4281 };
4282
4283 this.captureMouse = function(ev, mouseMoveHandler) {
4284 this.x = ev.x;
4285 this.y = ev.y;
4286
4287 this.isMousePressed = true;
4288 var renderer = this.editor.renderer;
4289 if (renderer.$keepTextAreaAtCursor)
4290 renderer.$keepTextAreaAtCursor = null;
4291
4292 var self = this;
4293 var onMouseMove = function(e) {
4294 if (!e) return;
4295 if (useragent.isWebKit && !e.which && self.releaseMouse)
4296 return self.releaseMouse();
4297
4298 self.x = e.clientX;
4299 self.y = e.clientY;
4300 mouseMoveHandler && mouseMoveHandler(e);
4301 self.mouseEvent = new MouseEvent(e, self.editor);
4302 self.$mouseMoved = true;
4303 };
4304
4305 var onCaptureEnd = function(e) {
4306 clearInterval(timerId);
4307 onCaptureInterval();
4308 self[self.state + "End"] && self[self.state + "End"](e);
4309 self.state = "";
4310 if (renderer.$keepTextAreaAtCursor == null) {
4311 renderer.$keepTextAreaAtCursor = true;
4312 renderer.$moveTextAreaToCursor();
4313 }
4314 self.isMousePressed = false;
4315 self.$onCaptureMouseMove = self.releaseMouse = null;
4316 e && self.onMouseEvent("mouseup", e);
4317 };
4318
4319 var onCaptureInterval = function() {
4320 self[self.state] && self[self.state]();
4321 self.$mouseMoved = false;
4322 };
4323
4324 if (useragent.isOldIE && ev.domEvent.type == "dblclick") {
4325 return setTimeout(function() {onCaptureEnd(ev);});
4326 }
4327
4328 self.$onCaptureMouseMove = onMouseMove;
4329 self.releaseMouse = event.capture(this.editor.container, onMouseMove, onCaptureEnd);
4330 var timerId = setInterval(onCaptureInterval, 20);
4331 };
4332 this.releaseMouse = null;
4333 this.cancelContextMenu = function() {
4334 var stop = function(e) {
4335 if (e && e.domEvent && e.domEvent.type != "contextmenu")
4336 return;
4337 this.editor.off("nativecontextmenu", stop);
4338 if (e && e.domEvent)
4339 event.stopEvent(e.domEvent);
4340 }.bind(this);
4341 setTimeout(stop, 10);
4342 this.editor.on("nativecontextmenu", stop);
4343 };
4344}).call(MouseHandler.prototype);
4345
4346config.defineOptions(MouseHandler.prototype, "mouseHandler", {
4347 scrollSpeed: {initialValue: 2},
4348 dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},
4349 dragEnabled: {initialValue: true},
4350 focusTimout: {initialValue: 0},
4351 tooltipFollowsMouse: {initialValue: true}
4352});
4353
4354
4355exports.MouseHandler = MouseHandler;
4356});
4357
4358ace.define("ace/mouse/fold_handler",["require","exports","module"], function(acequire, exports, module) {
4359
4360function FoldHandler(editor) {
4361
4362 editor.on("click", function(e) {
4363 var position = e.getDocumentPosition();
4364 var session = editor.session;
4365 var fold = session.getFoldAt(position.row, position.column, 1);
4366 if (fold) {
4367 if (e.getAccelKey())
4368 session.removeFold(fold);
4369 else
4370 session.expandFold(fold);
4371
4372 e.stop();
4373 }
4374 });
4375
4376 editor.on("gutterclick", function(e) {
4377 var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4378
4379 if (gutterRegion == "foldWidgets") {
4380 var row = e.getDocumentPosition().row;
4381 var session = editor.session;
4382 if (session.foldWidgets && session.foldWidgets[row])
4383 editor.session.onFoldWidgetClick(row, e);
4384 if (!editor.isFocused())
4385 editor.focus();
4386 e.stop();
4387 }
4388 });
4389
4390 editor.on("gutterdblclick", function(e) {
4391 var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4392
4393 if (gutterRegion == "foldWidgets") {
4394 var row = e.getDocumentPosition().row;
4395 var session = editor.session;
4396 var data = session.getParentFoldRangeData(row, true);
4397 var range = data.range || data.firstRange;
4398
4399 if (range) {
4400 row = range.start.row;
4401 var fold = session.getFoldAt(row, session.getLine(row).length, 1);
4402
4403 if (fold) {
4404 session.removeFold(fold);
4405 } else {
4406 session.addFold("...", range);
4407 editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
4408 }
4409 }
4410 e.stop();
4411 }
4412 });
4413}
4414
4415exports.FoldHandler = FoldHandler;
4416
4417});
4418
4419ace.define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"], function(acequire, exports, module) {
4420
4421var keyUtil = acequire("../lib/keys");
4422var event = acequire("../lib/event");
4423
4424var KeyBinding = function(editor) {
4425 this.$editor = editor;
4426 this.$data = {editor: editor};
4427 this.$handlers = [];
4428 this.setDefaultHandler(editor.commands);
4429};
4430
4431(function() {
4432 this.setDefaultHandler = function(kb) {
4433 this.removeKeyboardHandler(this.$defaultHandler);
4434 this.$defaultHandler = kb;
4435 this.addKeyboardHandler(kb, 0);
4436 };
4437
4438 this.setKeyboardHandler = function(kb) {
4439 var h = this.$handlers;
4440 if (h[h.length - 1] == kb)
4441 return;
4442
4443 while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler)
4444 this.removeKeyboardHandler(h[h.length - 1]);
4445
4446 this.addKeyboardHandler(kb, 1);
4447 };
4448
4449 this.addKeyboardHandler = function(kb, pos) {
4450 if (!kb)
4451 return;
4452 if (typeof kb == "function" && !kb.handleKeyboard)
4453 kb.handleKeyboard = kb;
4454 var i = this.$handlers.indexOf(kb);
4455 if (i != -1)
4456 this.$handlers.splice(i, 1);
4457
4458 if (pos == undefined)
4459 this.$handlers.push(kb);
4460 else
4461 this.$handlers.splice(pos, 0, kb);
4462
4463 if (i == -1 && kb.attach)
4464 kb.attach(this.$editor);
4465 };
4466
4467 this.removeKeyboardHandler = function(kb) {
4468 var i = this.$handlers.indexOf(kb);
4469 if (i == -1)
4470 return false;
4471 this.$handlers.splice(i, 1);
4472 kb.detach && kb.detach(this.$editor);
4473 return true;
4474 };
4475
4476 this.getKeyboardHandler = function() {
4477 return this.$handlers[this.$handlers.length - 1];
4478 };
4479
4480 this.getStatusText = function() {
4481 var data = this.$data;
4482 var editor = data.editor;
4483 return this.$handlers.map(function(h) {
4484 return h.getStatusText && h.getStatusText(editor, data) || "";
4485 }).filter(Boolean).join(" ");
4486 };
4487
4488 this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) {
4489 var toExecute;
4490 var success = false;
4491 var commands = this.$editor.commands;
4492
4493 for (var i = this.$handlers.length; i--;) {
4494 toExecute = this.$handlers[i].handleKeyboard(
4495 this.$data, hashId, keyString, keyCode, e
4496 );
4497 if (!toExecute || !toExecute.command)
4498 continue;
4499 if (toExecute.command == "null") {
4500 success = true;
4501 } else {
4502 success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
4503 }
4504 if (success && e && hashId != -1 &&
4505 toExecute.passEvent != true && toExecute.command.passEvent != true
4506 ) {
4507 event.stopEvent(e);
4508 }
4509 if (success)
4510 break;
4511 }
4512
4513 if (!success && hashId == -1) {
4514 toExecute = {command: "insertstring"};
4515 success = commands.exec("insertstring", this.$editor, keyString);
4516 }
4517
4518 if (success && this.$editor._signal)
4519 this.$editor._signal("keyboardActivity", toExecute);
4520
4521 return success;
4522 };
4523
4524 this.onCommandKey = function(e, hashId, keyCode) {
4525 var keyString = keyUtil.keyCodeToString(keyCode);
4526 this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
4527 };
4528
4529 this.onTextInput = function(text) {
4530 this.$callKeyboardHandlers(-1, text);
4531 };
4532
4533}).call(KeyBinding.prototype);
4534
4535exports.KeyBinding = KeyBinding;
4536});
4537
4538ace.define("ace/lib/bidiutil",["require","exports","module"], function(acequire, exports, module) {
4539var dir = 0, hiLevel = 0;
4540var lastArabic = false, hasUBAT_B = false, hasUBAT_S = false;
4541
4542var 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 ]
4543];
4544
4545var 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 ]
4546];
4547
4548var LTR = 0, RTL = 1;
4549
4550var L = 0;
4551var R = 1;
4552var EN = 2;
4553var AN = 3;
4554var ON = 4;
4555var B = 5;
4556var S = 6;
4557var AL = 7;
4558var WS = 8;
4559var CS = 9;
4560var ES = 10;
4561var ET = 11;
4562var NSM = 12;
4563var LRE = 13;
4564var RLE = 14;
4565var PDF = 15;
4566var LRO = 16;
4567var RLO = 17;
4568var BN = 18;
4569
4570var UnicodeTBL00 = [
4571BN,BN,BN,BN,BN,BN,BN,BN,BN,S,B,S,WS,B,BN,BN,
4572BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,B,B,B,S,
4573WS,ON,ON,ET,ET,ET,ON,ON,ON,ON,ON,ES,CS,ES,CS,CS,
4574EN,EN,EN,EN,EN,EN,EN,EN,EN,EN,CS,ON,ON,ON,ON,ON,
4575ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,
4576L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,ON,
4577ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,
4578L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,BN,
4579BN,BN,BN,BN,BN,B,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,
4580BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,
4581CS,ON,ET,ET,ET,ET,ON,ON,ON,ON,L,ON,ON,BN,ON,ON,
4582ET,ET,EN,EN,ON,L,ON,ON,ON,EN,L,ON,ON,ON,ON,ON
4583];
4584
4585var UnicodeTBL20 = [
4586WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,BN,BN,BN,L,R ,
4587ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4588ON,ON,ON,ON,ON,ON,ON,ON,WS,B,LRE,RLE,PDF,LRO,RLO,CS,
4589ET,ET,ET,ET,ET,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4590ON,ON,ON,ON,CS,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4591ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,WS
4592];
4593
4594function _computeLevels(chars, levels, len, charTypes) {
4595 var impTab = dir ? impTab_RTL : impTab_LTR
4596 , prevState = null, newClass = null, newLevel = null, newState = 0
4597 , action = null, cond = null, condPos = -1, i = null, ix = null, classes = [];
4598
4599 if (!charTypes) {
4600 for (i = 0, charTypes = []; i < len; i++) {
4601 charTypes[i] = _getCharacterType(chars[i]);
4602 }
4603 }
4604 hiLevel = dir;
4605 lastArabic = false;
4606 hasUBAT_B = false;
4607 hasUBAT_S = false;
4608 for (ix = 0; ix < len; ix++){
4609 prevState = newState;
4610 classes[ix] = newClass = _getCharClass(chars, charTypes, classes, ix);
4611 newState = impTab[prevState][newClass];
4612 action = newState & 0xF0;
4613 newState &= 0x0F;
4614 levels[ix] = newLevel = impTab[newState][5];
4615 if (action > 0){
4616 if (action == 0x10){
4617 for(i = condPos; i < ix; i++){
4618 levels[i] = 1;
4619 }
4620 condPos = -1;
4621 } else {
4622 condPos = -1;
4623 }
4624 }
4625 cond = impTab[newState][6];
4626 if (cond){
4627 if(condPos == -1){
4628 condPos = ix;
4629 }
4630 }else {
4631 if (condPos > -1){
4632 for(i = condPos; i < ix; i++){
4633 levels[i] = newLevel;
4634 }
4635 condPos = -1;
4636 }
4637 }
4638 if (charTypes[ix] == B){
4639 levels[ix] = 0;
4640 }
4641 hiLevel |= newLevel;
4642 }
4643 if (hasUBAT_S){
4644 for(i = 0; i < len; i++){
4645 if(charTypes[i] == S){
4646 levels[i] = dir;
4647 for(var j = i - 1; j >= 0; j--){
4648 if(charTypes[j] == WS){
4649 levels[j] = dir;
4650 }else {
4651 break;
4652 }
4653 }
4654 }
4655 }
4656 }
4657}
4658
4659function _invertLevel(lev, levels, _array) {
4660 if (hiLevel < lev){
4661 return;
4662 }
4663 if (lev == 1 && dir == RTL && !hasUBAT_B){
4664 _array.reverse();
4665 return;
4666 }
4667 var len = _array.length, start = 0, end, lo, hi, tmp;
4668 while(start < len){
4669 if (levels[start] >= lev){
4670 end = start + 1;
4671 while(end < len && levels[end] >= lev){
4672 end++;
4673 }
4674 for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){
4675 tmp = _array[lo];
4676 _array[lo] = _array[hi];
4677 _array[hi] = tmp;
4678 }
4679 start = end;
4680 }
4681 start++;
4682 }
4683}
4684
4685function _getCharClass(chars, types, classes, ix) {
4686 var cType = types[ix], wType, nType, len, i;
4687 switch(cType){
4688 case L:
4689 case R:
4690 lastArabic = false;
4691 case ON:
4692 case AN:
4693 return cType;
4694 case EN:
4695 return lastArabic ? AN : EN;
4696 case AL:
4697 lastArabic = true;
4698 return R;
4699 case WS:
4700 return ON;
4701 case CS:
4702 if (ix < 1 || (ix + 1) >= types.length ||
4703 ((wType = classes[ix - 1]) != EN && wType != AN) ||
4704 ((nType = types[ix + 1]) != EN && nType != AN)){
4705 return ON;
4706 }
4707 if (lastArabic){nType = AN;}
4708 return nType == wType ? nType : ON;
4709 case ES:
4710 wType = ix > 0 ? classes[ix - 1] : B;
4711 if (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){
4712 return EN;
4713 }
4714 return ON;
4715 case ET:
4716 if (ix > 0 && classes[ix - 1] == EN){
4717 return EN;
4718 }
4719 if (lastArabic){
4720 return ON;
4721 }
4722 i = ix + 1;
4723 len = types.length;
4724 while (i < len && types[i] == ET){
4725 i++;
4726 }
4727 if (i < len && types[i] == EN){
4728 return EN;
4729 }
4730 return ON;
4731 case NSM:
4732 len = types.length;
4733 i = ix + 1;
4734 while (i < len && types[i] == NSM){
4735 i++;
4736 }
4737 if (i < len){
4738 var c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E;
4739
4740 wType = types[i];
4741 if (rtlCandidate && (wType == R || wType == AL)){
4742 return R;
4743 }
4744 }
4745
4746 if (ix < 1 || (wType = types[ix - 1]) == B){
4747 return ON;
4748 }
4749 return classes[ix - 1];
4750 case B:
4751 lastArabic = false;
4752 hasUBAT_B = true;
4753 return dir;
4754 case S:
4755 hasUBAT_S = true;
4756 return ON;
4757 case LRE:
4758 case RLE:
4759 case LRO:
4760 case RLO:
4761 case PDF:
4762 lastArabic = false;
4763 case BN:
4764 return ON;
4765 }
4766}
4767
4768function _getCharacterType( ch ) {
4769 var uc = ch.charCodeAt(0), hi = uc >> 8;
4770
4771 if (hi == 0) {
4772 return ((uc > 0x00BF) ? L : UnicodeTBL00[uc]);
4773 } else if (hi == 5) {
4774 return (/[\u0591-\u05f4]/.test(ch) ? R : L);
4775 } else if (hi == 6) {
4776 if (/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(ch))
4777 return NSM;
4778 else if (/[\u0660-\u0669\u066b-\u066c]/.test(ch))
4779 return AN;
4780 else if (uc == 0x066A)
4781 return ET;
4782 else if (/[\u06f0-\u06f9]/.test(ch))
4783 return EN;
4784 else
4785 return AL;
4786 } else if (hi == 0x20 && uc <= 0x205F) {
4787 return UnicodeTBL20[uc & 0xFF];
4788 } else if (hi == 0xFE) {
4789 return (uc >= 0xFE70 ? AL : ON);
4790 }
4791 return ON;
4792}
4793exports.L = L;
4794exports.R = R;
4795exports.EN = EN;
4796exports.ON_R = 3;
4797exports.AN = 4;
4798exports.R_H = 5;
4799exports.B = 6;
4800
4801exports.DOT = "\xB7";
4802exports.doBidiReorder = function(text, textCharTypes, isRtl) {
4803 if (text.length < 2)
4804 return {};
4805
4806 var chars = text.split(""), logicalFromVisual = new Array(chars.length),
4807 bidiLevels = new Array(chars.length), levels = [];
4808
4809 dir = isRtl ? RTL : LTR;
4810
4811 _computeLevels(chars, levels, chars.length, textCharTypes);
4812
4813 for (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++);
4814
4815 _invertLevel(2, levels, logicalFromVisual);
4816 _invertLevel(1, levels, logicalFromVisual);
4817
4818 for (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width
4819 if (textCharTypes[i] === AN) {
4820 levels[i] = exports.AN;
4821 } else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE)
4822 || textCharTypes[i] === ON || textCharTypes[i] === BN)) {
4823 levels[i] = exports.ON_R;
4824 } else if ((i > 0 && chars[i - 1] === '\u0644') && /\u0622|\u0623|\u0625|\u0627/.test(chars[i])) {
4825 levels[i - 1] = levels[i] = exports.R_H;
4826 i++;
4827 }
4828 }
4829 if (chars[chars.length - 1] === exports.DOT)
4830 levels[chars.length - 1] = exports.B;
4831
4832 for (var i = 0; i < logicalFromVisual.length; i++) {
4833 bidiLevels[i] = levels[logicalFromVisual[i]];
4834 }
4835
4836 return {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels};
4837};
4838exports.hasBidiCharacters = function(text, textCharTypes){
4839 var ret = false;
4840 for (var i = 0; i < text.length; i++){
4841 textCharTypes[i] = _getCharacterType(text.charAt(i));
4842 if (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL))
4843 ret = true;
4844 }
4845 return ret;
4846};
4847exports.getVisualFromLogicalIdx = function(logIdx, rowMap) {
4848 for (var i = 0; i < rowMap.logicalFromVisual.length; i++) {
4849 if (rowMap.logicalFromVisual[i] == logIdx)
4850 return i;
4851 }
4852 return 0;
4853};
4854
4855});
4856
4857ace.define("ace/bidihandler",["require","exports","module","ace/lib/bidiutil","ace/lib/lang","ace/lib/useragent"], function(acequire, exports, module) {
4858
4859var bidiUtil = acequire("./lib/bidiutil");
4860var lang = acequire("./lib/lang");
4861var useragent = acequire("./lib/useragent");
4862var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
4863var BidiHandler = function(session) {
4864 this.session = session;
4865 this.bidiMap = {};
4866 this.currentRow = null;
4867 this.bidiUtil = bidiUtil;
4868 this.charWidths = [];
4869 this.EOL = "\xAC";
4870 this.showInvisibles = true;
4871 this.isRtlDir = false;
4872 this.line = "";
4873 this.wrapIndent = 0;
4874 this.isLastRow = false;
4875 this.EOF = "\xB6";
4876 this.seenBidi = false;
4877};
4878
4879(function() {
4880 this.isBidiRow = function(screenRow, docRow, splitIndex) {
4881 if (!this.seenBidi)
4882 return false;
4883 if (screenRow !== this.currentRow) {
4884 this.currentRow = screenRow;
4885 this.updateRowLine(docRow, splitIndex);
4886 this.updateBidiMap();
4887 }
4888 return this.bidiMap.bidiLevels;
4889 };
4890
4891 this.onChange = function(delta) {
4892 if (!this.seenBidi) {
4893 if (delta.action == "insert" && bidiRE.test(delta.lines.join("\n"))) {
4894 this.seenBidi = true;
4895 this.currentRow = null;
4896 }
4897 }
4898 else {
4899 this.currentRow = null;
4900 }
4901 };
4902
4903 this.getDocumentRow = function() {
4904 var docRow = 0;
4905 var rowCache = this.session.$screenRowCache;
4906 if (rowCache.length) {
4907 var index = this.session.$getRowCacheIndex(rowCache, this.currentRow);
4908 if (index >= 0)
4909 docRow = this.session.$docRowCache[index];
4910 }
4911
4912 return docRow;
4913 };
4914
4915 this.getSplitIndex = function() {
4916 var splitIndex = 0;
4917 var rowCache = this.session.$screenRowCache;
4918 if (rowCache.length) {
4919 var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow);
4920 while (this.currentRow - splitIndex > 0) {
4921 currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1);
4922 if (currentIndex !== prevIndex)
4923 break;
4924
4925 prevIndex = currentIndex;
4926 splitIndex++;
4927 }
4928 }
4929
4930 return splitIndex;
4931 };
4932
4933 this.updateRowLine = function(docRow, splitIndex) {
4934 if (docRow === undefined)
4935 docRow = this.getDocumentRow();
4936
4937 this.wrapIndent = 0;
4938 this.isLastRow = (docRow === this.session.getLength() - 1);
4939 this.line = this.session.getLine(docRow);
4940 if (this.session.$useWrapMode) {
4941 var splits = this.session.$wrapData[docRow];
4942 if (splits) {
4943 if (splitIndex === undefined)
4944 splitIndex = this.getSplitIndex();
4945
4946 if(splitIndex > 0 && splits.length) {
4947 this.wrapIndent = splits.indent;
4948 this.line = (splitIndex < splits.length) ?
4949 this.line.substring(splits[splitIndex - 1], splits[splits.length - 1]) :
4950 this.line.substring(splits[splits.length - 1]);
4951 } else {
4952 this.line = this.line.substring(0, splits[splitIndex]);
4953 }
4954 }
4955 }
4956 var session = this.session, shift = 0, size;
4957 this.line = this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g, function(ch, i){
4958 if (ch === '\t' || session.isFullWidth(ch.charCodeAt(0))) {
4959 size = (ch === '\t') ? session.getScreenTabSize(i + shift) : 2;
4960 shift += size - 1;
4961 return lang.stringRepeat(bidiUtil.DOT, size);
4962 }
4963 return ch;
4964 });
4965 };
4966
4967 this.updateBidiMap = function() {
4968 var textCharTypes = [], endOfLine = this.isLastRow ? this.EOF : this.EOL;
4969 var line = this.line + (this.showInvisibles ? endOfLine : bidiUtil.DOT);
4970 if (bidiUtil.hasBidiCharacters(line, textCharTypes)) {
4971 this.bidiMap = bidiUtil.doBidiReorder(line, textCharTypes, this.isRtlDir);
4972 } else {
4973 this.bidiMap = {};
4974 }
4975 };
4976 this.markAsDirty = function() {
4977 this.currentRow = null;
4978 };
4979 this.updateCharacterWidths = function(fontMetrics) {
4980 if (!this.seenBidi)
4981 return;
4982 if (this.characterWidth === fontMetrics.$characterSize.width)
4983 return;
4984
4985 var characterWidth = this.characterWidth = fontMetrics.$characterSize.width;
4986 var bidiCharWidth = fontMetrics.$measureCharWidth("\u05d4");
4987
4988 this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth;
4989 this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth;
4990 this.charWidths[bidiUtil.R_H] = useragent.isChrome ? bidiCharWidth : bidiCharWidth * 0.45;
4991 this.charWidths[bidiUtil.B] = 0;
4992
4993 this.currentRow = null;
4994 };
4995
4996 this.getShowInvisibles = function() {
4997 return this.showInvisibles;
4998 };
4999
5000 this.setShowInvisibles = function(showInvisibles) {
5001 this.showInvisibles = showInvisibles;
5002 this.currentRow = null;
5003 };
5004
5005 this.setEolChar = function(eolChar) {
5006 this.EOL = eolChar;
5007 };
5008
5009 this.setTextDir = function(isRtlDir) {
5010 this.isRtlDir = isRtlDir;
5011 };
5012 this.getPosLeft = function(col) {
5013 col -= this.wrapIndent;
5014 var visualIdx = bidiUtil.getVisualFromLogicalIdx(col > 0 ? col - 1 : 0, this.bidiMap),
5015 levels = this.bidiMap.bidiLevels, left = 0;
5016
5017 if (col === 0 && levels[visualIdx] % 2 !== 0)
5018 visualIdx++;
5019
5020 for (var i = 0; i < visualIdx; i++) {
5021 left += this.charWidths[levels[i]];
5022 }
5023
5024 if (col !== 0 && levels[visualIdx] % 2 === 0)
5025 left += this.charWidths[levels[visualIdx]];
5026
5027 if (this.wrapIndent)
5028 left += this.wrapIndent * this.charWidths[bidiUtil.L];
5029
5030 return left;
5031 };
5032 this.getSelections = function(startCol, endCol) {
5033 var map = this.bidiMap, levels = map.bidiLevels, level, offset = this.wrapIndent * this.charWidths[bidiUtil.L], selections = [],
5034 selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent,
5035 isSelected = false, isSelectedPrev = false, selectionStart = 0;
5036
5037 for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) {
5038 logIdx = map.logicalFromVisual[visIdx];
5039 level = levels[visIdx];
5040 isSelected = (logIdx >= selColMin) && (logIdx < selColMax);
5041 if (isSelected && !isSelectedPrev) {
5042 selectionStart = offset;
5043 } else if (!isSelected && isSelectedPrev) {
5044 selections.push({left: selectionStart, width: offset - selectionStart});
5045 }
5046 offset += this.charWidths[level];
5047 isSelectedPrev = isSelected;
5048 }
5049
5050 if (isSelected && (visIdx === levels.length)) {
5051 selections.push({left: selectionStart, width: offset - selectionStart});
5052 }
5053
5054 return selections;
5055 };
5056 this.offsetToCol = function(posX) {
5057 var logicalIdx = 0, posX = Math.max(posX, 0),
5058 offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels,
5059 charWidth = this.charWidths[levels[visualIdx]];
5060
5061 if (this.wrapIndent) {
5062 posX -= this.wrapIndent * this.charWidths[bidiUtil.L];
5063 }
5064
5065 while(posX > offset + charWidth/2) {
5066 offset += charWidth;
5067 if(visualIdx === levels.length - 1) {
5068 charWidth = 0;
5069 break;
5070 }
5071 charWidth = this.charWidths[levels[++visualIdx]];
5072 }
5073
5074 if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){
5075 if(posX < offset)
5076 visualIdx--;
5077 logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];
5078
5079 } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){
5080 logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx]
5081 : this.bidiMap.logicalFromVisual[visualIdx - 1]);
5082
5083 } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0))
5084 || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){
5085 logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx];
5086 } else {
5087 if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0)
5088 visualIdx--;
5089 logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];
5090 }
5091
5092 return (logicalIdx + this.wrapIndent);
5093 };
5094
5095}).call(BidiHandler.prototype);
5096
5097exports.BidiHandler = BidiHandler;
5098});
5099
5100ace.define("ace/range",["require","exports","module"], function(acequire, exports, module) {
5101var comparePoints = function(p1, p2) {
5102 return p1.row - p2.row || p1.column - p2.column;
5103};
5104var Range = function(startRow, startColumn, endRow, endColumn) {
5105 this.start = {
5106 row: startRow,
5107 column: startColumn
5108 };
5109
5110 this.end = {
5111 row: endRow,
5112 column: endColumn
5113 };
5114};
5115
5116(function() {
5117 this.isEqual = function(range) {
5118 return this.start.row === range.start.row &&
5119 this.end.row === range.end.row &&
5120 this.start.column === range.start.column &&
5121 this.end.column === range.end.column;
5122 };
5123 this.toString = function() {
5124 return ("Range: [" + this.start.row + "/" + this.start.column +
5125 "] -> [" + this.end.row + "/" + this.end.column + "]");
5126 };
5127
5128 this.contains = function(row, column) {
5129 return this.compare(row, column) == 0;
5130 };
5131 this.compareRange = function(range) {
5132 var cmp,
5133 end = range.end,
5134 start = range.start;
5135
5136 cmp = this.compare(end.row, end.column);
5137 if (cmp == 1) {
5138 cmp = this.compare(start.row, start.column);
5139 if (cmp == 1) {
5140 return 2;
5141 } else if (cmp == 0) {
5142 return 1;
5143 } else {
5144 return 0;
5145 }
5146 } else if (cmp == -1) {
5147 return -2;
5148 } else {
5149 cmp = this.compare(start.row, start.column);
5150 if (cmp == -1) {
5151 return -1;
5152 } else if (cmp == 1) {
5153 return 42;
5154 } else {
5155 return 0;
5156 }
5157 }
5158 };
5159 this.comparePoint = function(p) {
5160 return this.compare(p.row, p.column);
5161 };
5162 this.containsRange = function(range) {
5163 return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
5164 };
5165 this.intersects = function(range) {
5166 var cmp = this.compareRange(range);
5167 return (cmp == -1 || cmp == 0 || cmp == 1);
5168 };
5169 this.isEnd = function(row, column) {
5170 return this.end.row == row && this.end.column == column;
5171 };
5172 this.isStart = function(row, column) {
5173 return this.start.row == row && this.start.column == column;
5174 };
5175 this.setStart = function(row, column) {
5176 if (typeof row == "object") {
5177 this.start.column = row.column;
5178 this.start.row = row.row;
5179 } else {
5180 this.start.row = row;
5181 this.start.column = column;
5182 }
5183 };
5184 this.setEnd = function(row, column) {
5185 if (typeof row == "object") {
5186 this.end.column = row.column;
5187 this.end.row = row.row;
5188 } else {
5189 this.end.row = row;
5190 this.end.column = column;
5191 }
5192 };
5193 this.inside = function(row, column) {
5194 if (this.compare(row, column) == 0) {
5195 if (this.isEnd(row, column) || this.isStart(row, column)) {
5196 return false;
5197 } else {
5198 return true;
5199 }
5200 }
5201 return false;
5202 };
5203 this.insideStart = function(row, column) {
5204 if (this.compare(row, column) == 0) {
5205 if (this.isEnd(row, column)) {
5206 return false;
5207 } else {
5208 return true;
5209 }
5210 }
5211 return false;
5212 };
5213 this.insideEnd = function(row, column) {
5214 if (this.compare(row, column) == 0) {
5215 if (this.isStart(row, column)) {
5216 return false;
5217 } else {
5218 return true;
5219 }
5220 }
5221 return false;
5222 };
5223 this.compare = function(row, column) {
5224 if (!this.isMultiLine()) {
5225 if (row === this.start.row) {
5226 return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
5227 }
5228 }
5229
5230 if (row < this.start.row)
5231 return -1;
5232
5233 if (row > this.end.row)
5234 return 1;
5235
5236 if (this.start.row === row)
5237 return column >= this.start.column ? 0 : -1;
5238
5239 if (this.end.row === row)
5240 return column <= this.end.column ? 0 : 1;
5241
5242 return 0;
5243 };
5244 this.compareStart = function(row, column) {
5245 if (this.start.row == row && this.start.column == column) {
5246 return -1;
5247 } else {
5248 return this.compare(row, column);
5249 }
5250 };
5251 this.compareEnd = function(row, column) {
5252 if (this.end.row == row && this.end.column == column) {
5253 return 1;
5254 } else {
5255 return this.compare(row, column);
5256 }
5257 };
5258 this.compareInside = function(row, column) {
5259 if (this.end.row == row && this.end.column == column) {
5260 return 1;
5261 } else if (this.start.row == row && this.start.column == column) {
5262 return -1;
5263 } else {
5264 return this.compare(row, column);
5265 }
5266 };
5267 this.clipRows = function(firstRow, lastRow) {
5268 if (this.end.row > lastRow)
5269 var end = {row: lastRow + 1, column: 0};
5270 else if (this.end.row < firstRow)
5271 var end = {row: firstRow, column: 0};
5272
5273 if (this.start.row > lastRow)
5274 var start = {row: lastRow + 1, column: 0};
5275 else if (this.start.row < firstRow)
5276 var start = {row: firstRow, column: 0};
5277
5278 return Range.fromPoints(start || this.start, end || this.end);
5279 };
5280 this.extend = function(row, column) {
5281 var cmp = this.compare(row, column);
5282
5283 if (cmp == 0)
5284 return this;
5285 else if (cmp == -1)
5286 var start = {row: row, column: column};
5287 else
5288 var end = {row: row, column: column};
5289
5290 return Range.fromPoints(start || this.start, end || this.end);
5291 };
5292
5293 this.isEmpty = function() {
5294 return (this.start.row === this.end.row && this.start.column === this.end.column);
5295 };
5296 this.isMultiLine = function() {
5297 return (this.start.row !== this.end.row);
5298 };
5299 this.clone = function() {
5300 return Range.fromPoints(this.start, this.end);
5301 };
5302 this.collapseRows = function() {
5303 if (this.end.column == 0)
5304 return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);
5305 else
5306 return new Range(this.start.row, 0, this.end.row, 0);
5307 };
5308 this.toScreenRange = function(session) {
5309 var screenPosStart = session.documentToScreenPosition(this.start);
5310 var screenPosEnd = session.documentToScreenPosition(this.end);
5311
5312 return new Range(
5313 screenPosStart.row, screenPosStart.column,
5314 screenPosEnd.row, screenPosEnd.column
5315 );
5316 };
5317 this.moveBy = function(row, column) {
5318 this.start.row += row;
5319 this.start.column += column;
5320 this.end.row += row;
5321 this.end.column += column;
5322 };
5323
5324}).call(Range.prototype);
5325Range.fromPoints = function(start, end) {
5326 return new Range(start.row, start.column, end.row, end.column);
5327};
5328Range.comparePoints = comparePoints;
5329
5330Range.comparePoints = function(p1, p2) {
5331 return p1.row - p2.row || p1.column - p2.column;
5332};
5333
5334
5335exports.Range = Range;
5336});
5337
5338ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"], function(acequire, exports, module) {
5339
5340var oop = acequire("./lib/oop");
5341var lang = acequire("./lib/lang");
5342var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
5343var Range = acequire("./range").Range;
5344var Selection = function(session) {
5345 this.session = session;
5346 this.doc = session.getDocument();
5347
5348 this.clearSelection();
5349 this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
5350 this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
5351
5352 var self = this;
5353 this.lead.on("change", function(e) {
5354 self._emit("changeCursor");
5355 if (!self.$isEmpty)
5356 self._emit("changeSelection");
5357 if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)
5358 self.$desiredColumn = null;
5359 });
5360
5361 this.selectionAnchor.on("change", function() {
5362 if (!self.$isEmpty)
5363 self._emit("changeSelection");
5364 });
5365};
5366
5367(function() {
5368
5369 oop.implement(this, EventEmitter);
5370 this.isEmpty = function() {
5371 return (this.$isEmpty || (
5372 this.anchor.row == this.lead.row &&
5373 this.anchor.column == this.lead.column
5374 ));
5375 };
5376 this.isMultiLine = function() {
5377 if (this.isEmpty()) {
5378 return false;
5379 }
5380
5381 return this.getRange().isMultiLine();
5382 };
5383 this.getCursor = function() {
5384 return this.lead.getPosition();
5385 };
5386 this.setSelectionAnchor = function(row, column) {
5387 this.anchor.setPosition(row, column);
5388
5389 if (this.$isEmpty) {
5390 this.$isEmpty = false;
5391 this._emit("changeSelection");
5392 }
5393 };
5394 this.getSelectionAnchor = function() {
5395 if (this.$isEmpty)
5396 return this.getSelectionLead();
5397 else
5398 return this.anchor.getPosition();
5399 };
5400 this.getSelectionLead = function() {
5401 return this.lead.getPosition();
5402 };
5403 this.shiftSelection = function(columns) {
5404 if (this.$isEmpty) {
5405 this.moveCursorTo(this.lead.row, this.lead.column + columns);
5406 return;
5407 }
5408
5409 var anchor = this.getSelectionAnchor();
5410 var lead = this.getSelectionLead();
5411
5412 var isBackwards = this.isBackwards();
5413
5414 if (!isBackwards || anchor.column !== 0)
5415 this.setSelectionAnchor(anchor.row, anchor.column + columns);
5416
5417 if (isBackwards || lead.column !== 0) {
5418 this.$moveSelection(function() {
5419 this.moveCursorTo(lead.row, lead.column + columns);
5420 });
5421 }
5422 };
5423 this.isBackwards = function() {
5424 var anchor = this.anchor;
5425 var lead = this.lead;
5426 return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
5427 };
5428 this.getRange = function() {
5429 var anchor = this.anchor;
5430 var lead = this.lead;
5431
5432 if (this.isEmpty())
5433 return Range.fromPoints(lead, lead);
5434
5435 if (this.isBackwards()) {
5436 return Range.fromPoints(lead, anchor);
5437 }
5438 else {
5439 return Range.fromPoints(anchor, lead);
5440 }
5441 };
5442 this.clearSelection = function() {
5443 if (!this.$isEmpty) {
5444 this.$isEmpty = true;
5445 this._emit("changeSelection");
5446 }
5447 };
5448 this.selectAll = function() {
5449 var lastRow = this.doc.getLength() - 1;
5450 this.setSelectionAnchor(0, 0);
5451 this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);
5452 };
5453 this.setRange =
5454 this.setSelectionRange = function(range, reverse) {
5455 if (reverse) {
5456 this.setSelectionAnchor(range.end.row, range.end.column);
5457 this.selectTo(range.start.row, range.start.column);
5458 } else {
5459 this.setSelectionAnchor(range.start.row, range.start.column);
5460 this.selectTo(range.end.row, range.end.column);
5461 }
5462 if (this.getRange().isEmpty())
5463 this.$isEmpty = true;
5464 this.$desiredColumn = null;
5465 };
5466
5467 this.$moveSelection = function(mover) {
5468 var lead = this.lead;
5469 if (this.$isEmpty)
5470 this.setSelectionAnchor(lead.row, lead.column);
5471
5472 mover.call(this);
5473 };
5474 this.selectTo = function(row, column) {
5475 this.$moveSelection(function() {
5476 this.moveCursorTo(row, column);
5477 });
5478 };
5479 this.selectToPosition = function(pos) {
5480 this.$moveSelection(function() {
5481 this.moveCursorToPosition(pos);
5482 });
5483 };
5484 this.moveTo = function(row, column) {
5485 this.clearSelection();
5486 this.moveCursorTo(row, column);
5487 };
5488 this.moveToPosition = function(pos) {
5489 this.clearSelection();
5490 this.moveCursorToPosition(pos);
5491 };
5492 this.selectUp = function() {
5493 this.$moveSelection(this.moveCursorUp);
5494 };
5495 this.selectDown = function() {
5496 this.$moveSelection(this.moveCursorDown);
5497 };
5498 this.selectRight = function() {
5499 this.$moveSelection(this.moveCursorRight);
5500 };
5501 this.selectLeft = function() {
5502 this.$moveSelection(this.moveCursorLeft);
5503 };
5504 this.selectLineStart = function() {
5505 this.$moveSelection(this.moveCursorLineStart);
5506 };
5507 this.selectLineEnd = function() {
5508 this.$moveSelection(this.moveCursorLineEnd);
5509 };
5510 this.selectFileEnd = function() {
5511 this.$moveSelection(this.moveCursorFileEnd);
5512 };
5513 this.selectFileStart = function() {
5514 this.$moveSelection(this.moveCursorFileStart);
5515 };
5516 this.selectWordRight = function() {
5517 this.$moveSelection(this.moveCursorWordRight);
5518 };
5519 this.selectWordLeft = function() {
5520 this.$moveSelection(this.moveCursorWordLeft);
5521 };
5522 this.getWordRange = function(row, column) {
5523 if (typeof column == "undefined") {
5524 var cursor = row || this.lead;
5525 row = cursor.row;
5526 column = cursor.column;
5527 }
5528 return this.session.getWordRange(row, column);
5529 };
5530 this.selectWord = function() {
5531 this.setSelectionRange(this.getWordRange());
5532 };
5533 this.selectAWord = function() {
5534 var cursor = this.getCursor();
5535 var range = this.session.getAWordRange(cursor.row, cursor.column);
5536 this.setSelectionRange(range);
5537 };
5538
5539 this.getLineRange = function(row, excludeLastChar) {
5540 var rowStart = typeof row == "number" ? row : this.lead.row;
5541 var rowEnd;
5542
5543 var foldLine = this.session.getFoldLine(rowStart);
5544 if (foldLine) {
5545 rowStart = foldLine.start.row;
5546 rowEnd = foldLine.end.row;
5547 } else {
5548 rowEnd = rowStart;
5549 }
5550 if (excludeLastChar === true)
5551 return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
5552 else
5553 return new Range(rowStart, 0, rowEnd + 1, 0);
5554 };
5555 this.selectLine = function() {
5556 this.setSelectionRange(this.getLineRange());
5557 };
5558 this.moveCursorUp = function() {
5559 this.moveCursorBy(-1, 0);
5560 };
5561 this.moveCursorDown = function() {
5562 this.moveCursorBy(1, 0);
5563 };
5564 this.wouldMoveIntoSoftTab = function(cursor, tabSize, direction) {
5565 var start = cursor.column;
5566 var end = cursor.column + tabSize;
5567
5568 if (direction < 0) {
5569 start = cursor.column - tabSize;
5570 end = cursor.column;
5571 }
5572 return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(" ").length-1 == tabSize;
5573 };
5574 this.moveCursorLeft = function() {
5575 var cursor = this.lead.getPosition(),
5576 fold;
5577
5578 if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
5579 this.moveCursorTo(fold.start.row, fold.start.column);
5580 } else if (cursor.column === 0) {
5581 if (cursor.row > 0) {
5582 this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
5583 }
5584 }
5585 else {
5586 var tabSize = this.session.getTabSize();
5587 if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) {
5588 this.moveCursorBy(0, -tabSize);
5589 } else {
5590 this.moveCursorBy(0, -1);
5591 }
5592 }
5593 };
5594 this.moveCursorRight = function() {
5595 var cursor = this.lead.getPosition(),
5596 fold;
5597 if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
5598 this.moveCursorTo(fold.end.row, fold.end.column);
5599 }
5600 else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
5601 if (this.lead.row < this.doc.getLength() - 1) {
5602 this.moveCursorTo(this.lead.row + 1, 0);
5603 }
5604 }
5605 else {
5606 var tabSize = this.session.getTabSize();
5607 var cursor = this.lead;
5608 if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) {
5609 this.moveCursorBy(0, tabSize);
5610 } else {
5611 this.moveCursorBy(0, 1);
5612 }
5613 }
5614 };
5615 this.moveCursorLineStart = function() {
5616 var row = this.lead.row;
5617 var column = this.lead.column;
5618 var screenRow = this.session.documentToScreenRow(row, column);
5619 var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);
5620 var beforeCursor = this.session.getDisplayLine(
5621 row, null, firstColumnPosition.row,
5622 firstColumnPosition.column
5623 );
5624
5625 var leadingSpace = beforeCursor.match(/^\s*/);
5626 if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)
5627 firstColumnPosition.column += leadingSpace[0].length;
5628 this.moveCursorToPosition(firstColumnPosition);
5629 };
5630 this.moveCursorLineEnd = function() {
5631 var lead = this.lead;
5632 var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
5633 if (this.lead.column == lineEnd.column) {
5634 var line = this.session.getLine(lineEnd.row);
5635 if (lineEnd.column == line.length) {
5636 var textEnd = line.search(/\s+$/);
5637 if (textEnd > 0)
5638 lineEnd.column = textEnd;
5639 }
5640 }
5641
5642 this.moveCursorTo(lineEnd.row, lineEnd.column);
5643 };
5644 this.moveCursorFileEnd = function() {
5645 var row = this.doc.getLength() - 1;
5646 var column = this.doc.getLine(row).length;
5647 this.moveCursorTo(row, column);
5648 };
5649 this.moveCursorFileStart = function() {
5650 this.moveCursorTo(0, 0);
5651 };
5652 this.moveCursorLongWordRight = function() {
5653 var row = this.lead.row;
5654 var column = this.lead.column;
5655 var line = this.doc.getLine(row);
5656 var rightOfCursor = line.substring(column);
5657 this.session.nonTokenRe.lastIndex = 0;
5658 this.session.tokenRe.lastIndex = 0;
5659 var fold = this.session.getFoldAt(row, column, 1);
5660 if (fold) {
5661 this.moveCursorTo(fold.end.row, fold.end.column);
5662 return;
5663 }
5664 if (this.session.nonTokenRe.exec(rightOfCursor)) {
5665 column += this.session.nonTokenRe.lastIndex;
5666 this.session.nonTokenRe.lastIndex = 0;
5667 rightOfCursor = line.substring(column);
5668 }
5669 if (column >= line.length) {
5670 this.moveCursorTo(row, line.length);
5671 this.moveCursorRight();
5672 if (row < this.doc.getLength() - 1)
5673 this.moveCursorWordRight();
5674 return;
5675 }
5676 if (this.session.tokenRe.exec(rightOfCursor)) {
5677 column += this.session.tokenRe.lastIndex;
5678 this.session.tokenRe.lastIndex = 0;
5679 }
5680
5681 this.moveCursorTo(row, column);
5682 };
5683 this.moveCursorLongWordLeft = function() {
5684 var row = this.lead.row;
5685 var column = this.lead.column;
5686 var fold;
5687 if (fold = this.session.getFoldAt(row, column, -1)) {
5688 this.moveCursorTo(fold.start.row, fold.start.column);
5689 return;
5690 }
5691
5692 var str = this.session.getFoldStringAt(row, column, -1);
5693 if (str == null) {
5694 str = this.doc.getLine(row).substring(0, column);
5695 }
5696
5697 var leftOfCursor = lang.stringReverse(str);
5698 this.session.nonTokenRe.lastIndex = 0;
5699 this.session.tokenRe.lastIndex = 0;
5700 if (this.session.nonTokenRe.exec(leftOfCursor)) {
5701 column -= this.session.nonTokenRe.lastIndex;
5702 leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
5703 this.session.nonTokenRe.lastIndex = 0;
5704 }
5705 if (column <= 0) {
5706 this.moveCursorTo(row, 0);
5707 this.moveCursorLeft();
5708 if (row > 0)
5709 this.moveCursorWordLeft();
5710 return;
5711 }
5712 if (this.session.tokenRe.exec(leftOfCursor)) {
5713 column -= this.session.tokenRe.lastIndex;
5714 this.session.tokenRe.lastIndex = 0;
5715 }
5716
5717 this.moveCursorTo(row, column);
5718 };
5719
5720 this.$shortWordEndIndex = function(rightOfCursor) {
5721 var index = 0, ch;
5722 var whitespaceRe = /\s/;
5723 var tokenRe = this.session.tokenRe;
5724
5725 tokenRe.lastIndex = 0;
5726 if (this.session.tokenRe.exec(rightOfCursor)) {
5727 index = this.session.tokenRe.lastIndex;
5728 } else {
5729 while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
5730 index ++;
5731
5732 if (index < 1) {
5733 tokenRe.lastIndex = 0;
5734 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
5735 tokenRe.lastIndex = 0;
5736 index ++;
5737 if (whitespaceRe.test(ch)) {
5738 if (index > 2) {
5739 index--;
5740 break;
5741 } else {
5742 while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
5743 index ++;
5744 if (index > 2)
5745 break;
5746 }
5747 }
5748 }
5749 }
5750 }
5751 tokenRe.lastIndex = 0;
5752
5753 return index;
5754 };
5755
5756 this.moveCursorShortWordRight = function() {
5757 var row = this.lead.row;
5758 var column = this.lead.column;
5759 var line = this.doc.getLine(row);
5760 var rightOfCursor = line.substring(column);
5761
5762 var fold = this.session.getFoldAt(row, column, 1);
5763 if (fold)
5764 return this.moveCursorTo(fold.end.row, fold.end.column);
5765
5766 if (column == line.length) {
5767 var l = this.doc.getLength();
5768 do {
5769 row++;
5770 rightOfCursor = this.doc.getLine(row);
5771 } while (row < l && /^\s*$/.test(rightOfCursor));
5772
5773 if (!/^\s+/.test(rightOfCursor))
5774 rightOfCursor = "";
5775 column = 0;
5776 }
5777
5778 var index = this.$shortWordEndIndex(rightOfCursor);
5779
5780 this.moveCursorTo(row, column + index);
5781 };
5782
5783 this.moveCursorShortWordLeft = function() {
5784 var row = this.lead.row;
5785 var column = this.lead.column;
5786
5787 var fold;
5788 if (fold = this.session.getFoldAt(row, column, -1))
5789 return this.moveCursorTo(fold.start.row, fold.start.column);
5790
5791 var line = this.session.getLine(row).substring(0, column);
5792 if (column === 0) {
5793 do {
5794 row--;
5795 line = this.doc.getLine(row);
5796 } while (row > 0 && /^\s*$/.test(line));
5797
5798 column = line.length;
5799 if (!/\s+$/.test(line))
5800 line = "";
5801 }
5802
5803 var leftOfCursor = lang.stringReverse(line);
5804 var index = this.$shortWordEndIndex(leftOfCursor);
5805
5806 return this.moveCursorTo(row, column - index);
5807 };
5808
5809 this.moveCursorWordRight = function() {
5810 if (this.session.$selectLongWords)
5811 this.moveCursorLongWordRight();
5812 else
5813 this.moveCursorShortWordRight();
5814 };
5815
5816 this.moveCursorWordLeft = function() {
5817 if (this.session.$selectLongWords)
5818 this.moveCursorLongWordLeft();
5819 else
5820 this.moveCursorShortWordLeft();
5821 };
5822 this.moveCursorBy = function(rows, chars) {
5823 var screenPos = this.session.documentToScreenPosition(
5824 this.lead.row,
5825 this.lead.column
5826 );
5827
5828 var offsetX;
5829
5830 if (chars === 0) {
5831 if (rows !== 0) {
5832 if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) {
5833 offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column);
5834 screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]);
5835 } else {
5836 offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0];
5837 }
5838 }
5839
5840 if (this.$desiredColumn)
5841 screenPos.column = this.$desiredColumn;
5842 else
5843 this.$desiredColumn = screenPos.column;
5844 }
5845
5846 var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);
5847
5848 if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {
5849 if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) {
5850 if (docPos.row > 0 || rows > 0)
5851 docPos.row++;
5852 }
5853 }
5854 this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
5855 };
5856 this.moveCursorToPosition = function(position) {
5857 this.moveCursorTo(position.row, position.column);
5858 };
5859 this.moveCursorTo = function(row, column, keepDesiredColumn) {
5860 var fold = this.session.getFoldAt(row, column, 1);
5861 if (fold) {
5862 row = fold.start.row;
5863 column = fold.start.column;
5864 }
5865
5866 this.$keepDesiredColumnOnChange = true;
5867 var line = this.session.getLine(row);
5868 if (/[\uDC00-\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) {
5869 if (this.lead.row == row && this.lead.column == column + 1)
5870 column = column - 1;
5871 else
5872 column = column + 1;
5873 }
5874 this.lead.setPosition(row, column);
5875 this.$keepDesiredColumnOnChange = false;
5876
5877 if (!keepDesiredColumn)
5878 this.$desiredColumn = null;
5879 };
5880 this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
5881 var pos = this.session.screenToDocumentPosition(row, column);
5882 this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
5883 };
5884 this.detach = function() {
5885 this.lead.detach();
5886 this.anchor.detach();
5887 this.session = this.doc = null;
5888 };
5889
5890 this.fromOrientedRange = function(range) {
5891 this.setSelectionRange(range, range.cursor == range.start);
5892 this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
5893 };
5894
5895 this.toOrientedRange = function(range) {
5896 var r = this.getRange();
5897 if (range) {
5898 range.start.column = r.start.column;
5899 range.start.row = r.start.row;
5900 range.end.column = r.end.column;
5901 range.end.row = r.end.row;
5902 } else {
5903 range = r;
5904 }
5905
5906 range.cursor = this.isBackwards() ? range.start : range.end;
5907 range.desiredColumn = this.$desiredColumn;
5908 return range;
5909 };
5910 this.getRangeOfMovements = function(func) {
5911 var start = this.getCursor();
5912 try {
5913 func(this);
5914 var end = this.getCursor();
5915 return Range.fromPoints(start,end);
5916 } catch(e) {
5917 return Range.fromPoints(start,start);
5918 } finally {
5919 this.moveCursorToPosition(start);
5920 }
5921 };
5922
5923 this.toJSON = function() {
5924 if (this.rangeCount) {
5925 var data = this.ranges.map(function(r) {
5926 var r1 = r.clone();
5927 r1.isBackwards = r.cursor == r.start;
5928 return r1;
5929 });
5930 } else {
5931 var data = this.getRange();
5932 data.isBackwards = this.isBackwards();
5933 }
5934 return data;
5935 };
5936
5937 this.fromJSON = function(data) {
5938 if (data.start == undefined) {
5939 if (this.rangeList) {
5940 this.toSingleRange(data[0]);
5941 for (var i = data.length; i--; ) {
5942 var r = Range.fromPoints(data[i].start, data[i].end);
5943 if (data[i].isBackwards)
5944 r.cursor = r.start;
5945 this.addRange(r, true);
5946 }
5947 return;
5948 } else
5949 data = data[0];
5950 }
5951 if (this.rangeList)
5952 this.toSingleRange(data);
5953 this.setSelectionRange(data, data.isBackwards);
5954 };
5955
5956 this.isEqual = function(data) {
5957 if ((data.length || this.rangeCount) && data.length != this.rangeCount)
5958 return false;
5959 if (!data.length || !this.ranges)
5960 return this.getRange().isEqual(data);
5961
5962 for (var i = this.ranges.length; i--; ) {
5963 if (!this.ranges[i].isEqual(data[i]))
5964 return false;
5965 }
5966 return true;
5967 };
5968
5969}).call(Selection.prototype);
5970
5971exports.Selection = Selection;
5972});
5973
5974ace.define("ace/tokenizer",["require","exports","module","ace/config"], function(acequire, exports, module) {
5975
5976var config = acequire("./config");
5977var MAX_TOKEN_COUNT = 2000;
5978var Tokenizer = function(rules) {
5979 this.states = rules;
5980
5981 this.regExps = {};
5982 this.matchMappings = {};
5983 for (var key in this.states) {
5984 var state = this.states[key];
5985 var ruleRegExps = [];
5986 var matchTotal = 0;
5987 var mapping = this.matchMappings[key] = {defaultToken: "text"};
5988 var flag = "g";
5989
5990 var splitterRurles = [];
5991 for (var i = 0; i < state.length; i++) {
5992 var rule = state[i];
5993 if (rule.defaultToken)
5994 mapping.defaultToken = rule.defaultToken;
5995 if (rule.caseInsensitive)
5996 flag = "gi";
5997 if (rule.regex == null)
5998 continue;
5999
6000 if (rule.regex instanceof RegExp)
6001 rule.regex = rule.regex.toString().slice(1, -1);
6002 var adjustedregex = rule.regex;
6003 var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
6004 if (Array.isArray(rule.token)) {
6005 if (rule.token.length == 1 || matchcount == 1) {
6006 rule.token = rule.token[0];
6007 } else if (matchcount - 1 != rule.token.length) {
6008 this.reportError("number of classes and regexp groups doesn't match", {
6009 rule: rule,
6010 groupCount: matchcount - 1
6011 });
6012 rule.token = rule.token[0];
6013 } else {
6014 rule.tokenArray = rule.token;
6015 rule.token = null;
6016 rule.onMatch = this.$arrayTokens;
6017 }
6018 } else if (typeof rule.token == "function" && !rule.onMatch) {
6019 if (matchcount > 1)
6020 rule.onMatch = this.$applyToken;
6021 else
6022 rule.onMatch = rule.token;
6023 }
6024
6025 if (matchcount > 1) {
6026 if (/\\\d/.test(rule.regex)) {
6027 adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) {
6028 return "\\" + (parseInt(digit, 10) + matchTotal + 1);
6029 });
6030 } else {
6031 matchcount = 1;
6032 adjustedregex = this.removeCapturingGroups(rule.regex);
6033 }
6034 if (!rule.splitRegex && typeof rule.token != "string")
6035 splitterRurles.push(rule); // flag will be known only at the very end
6036 }
6037
6038 mapping[matchTotal] = i;
6039 matchTotal += matchcount;
6040
6041 ruleRegExps.push(adjustedregex);
6042 if (!rule.onMatch)
6043 rule.onMatch = null;
6044 }
6045
6046 if (!ruleRegExps.length) {
6047 mapping[0] = 0;
6048 ruleRegExps.push("$");
6049 }
6050
6051 splitterRurles.forEach(function(rule) {
6052 rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
6053 }, this);
6054
6055 this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
6056 }
6057};
6058
6059(function() {
6060 this.$setMaxTokenCount = function(m) {
6061 MAX_TOKEN_COUNT = m | 0;
6062 };
6063
6064 this.$applyToken = function(str) {
6065 var values = this.splitRegex.exec(str).slice(1);
6066 var types = this.token.apply(this, values);
6067 if (typeof types === "string")
6068 return [{type: types, value: str}];
6069
6070 var tokens = [];
6071 for (var i = 0, l = types.length; i < l; i++) {
6072 if (values[i])
6073 tokens[tokens.length] = {
6074 type: types[i],
6075 value: values[i]
6076 };
6077 }
6078 return tokens;
6079 };
6080
6081 this.$arrayTokens = function(str) {
6082 if (!str)
6083 return [];
6084 var values = this.splitRegex.exec(str);
6085 if (!values)
6086 return "text";
6087 var tokens = [];
6088 var types = this.tokenArray;
6089 for (var i = 0, l = types.length; i < l; i++) {
6090 if (values[i + 1])
6091 tokens[tokens.length] = {
6092 type: types[i],
6093 value: values[i + 1]
6094 };
6095 }
6096 return tokens;
6097 };
6098
6099 this.removeCapturingGroups = function(src) {
6100 var r = src.replace(
6101 /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
6102 function(x, y) {return y ? "(?:" : x;}
6103 );
6104 return r;
6105 };
6106
6107 this.createSplitterRegexp = function(src, flag) {
6108 if (src.indexOf("(?=") != -1) {
6109 var stack = 0;
6110 var inChClass = false;
6111 var lastCapture = {};
6112 src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function(
6113 m, esc, parenOpen, parenClose, square, index
6114 ) {
6115 if (inChClass) {
6116 inChClass = square != "]";
6117 } else if (square) {
6118 inChClass = true;
6119 } else if (parenClose) {
6120 if (stack == lastCapture.stack) {
6121 lastCapture.end = index+1;
6122 lastCapture.stack = -1;
6123 }
6124 stack--;
6125 } else if (parenOpen) {
6126 stack++;
6127 if (parenOpen.length != 1) {
6128 lastCapture.stack = stack;
6129 lastCapture.start = index;
6130 }
6131 }
6132 return m;
6133 });
6134
6135 if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
6136 src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
6137 }
6138 if (src.charAt(0) != "^") src = "^" + src;
6139 if (src.charAt(src.length - 1) != "$") src += "$";
6140
6141 return new RegExp(src, (flag||"").replace("g", ""));
6142 };
6143 this.getLineTokens = function(line, startState) {
6144 if (startState && typeof startState != "string") {
6145 var stack = startState.slice(0);
6146 startState = stack[0];
6147 if (startState === "#tmp") {
6148 stack.shift();
6149 startState = stack.shift();
6150 }
6151 } else
6152 var stack = [];
6153
6154 var currentState = startState || "start";
6155 var state = this.states[currentState];
6156 if (!state) {
6157 currentState = "start";
6158 state = this.states[currentState];
6159 }
6160 var mapping = this.matchMappings[currentState];
6161 var re = this.regExps[currentState];
6162 re.lastIndex = 0;
6163
6164 var match, tokens = [];
6165 var lastIndex = 0;
6166 var matchAttempts = 0;
6167
6168 var token = {type: null, value: ""};
6169
6170 while (match = re.exec(line)) {
6171 var type = mapping.defaultToken;
6172 var rule = null;
6173 var value = match[0];
6174 var index = re.lastIndex;
6175
6176 if (index - value.length > lastIndex) {
6177 var skipped = line.substring(lastIndex, index - value.length);
6178 if (token.type == type) {
6179 token.value += skipped;
6180 } else {
6181 if (token.type)
6182 tokens.push(token);
6183 token = {type: type, value: skipped};
6184 }
6185 }
6186
6187 for (var i = 0; i < match.length-2; i++) {
6188 if (match[i + 1] === undefined)
6189 continue;
6190
6191 rule = state[mapping[i]];
6192
6193 if (rule.onMatch)
6194 type = rule.onMatch(value, currentState, stack, line);
6195 else
6196 type = rule.token;
6197
6198 if (rule.next) {
6199 if (typeof rule.next == "string") {
6200 currentState = rule.next;
6201 } else {
6202 currentState = rule.next(currentState, stack);
6203 }
6204
6205 state = this.states[currentState];
6206 if (!state) {
6207 this.reportError("state doesn't exist", currentState);
6208 currentState = "start";
6209 state = this.states[currentState];
6210 }
6211 mapping = this.matchMappings[currentState];
6212 lastIndex = index;
6213 re = this.regExps[currentState];
6214 re.lastIndex = index;
6215 }
6216 if (rule.consumeLineEnd)
6217 lastIndex = index;
6218 break;
6219 }
6220
6221 if (value) {
6222 if (typeof type === "string") {
6223 if ((!rule || rule.merge !== false) && token.type === type) {
6224 token.value += value;
6225 } else {
6226 if (token.type)
6227 tokens.push(token);
6228 token = {type: type, value: value};
6229 }
6230 } else if (type) {
6231 if (token.type)
6232 tokens.push(token);
6233 token = {type: null, value: ""};
6234 for (var i = 0; i < type.length; i++)
6235 tokens.push(type[i]);
6236 }
6237 }
6238
6239 if (lastIndex == line.length)
6240 break;
6241
6242 lastIndex = index;
6243
6244 if (matchAttempts++ > MAX_TOKEN_COUNT) {
6245 if (matchAttempts > 2 * line.length) {
6246 this.reportError("infinite loop with in ace tokenizer", {
6247 startState: startState,
6248 line: line
6249 });
6250 }
6251 while (lastIndex < line.length) {
6252 if (token.type)
6253 tokens.push(token);
6254 token = {
6255 value: line.substring(lastIndex, lastIndex += 2000),
6256 type: "overflow"
6257 };
6258 }
6259 currentState = "start";
6260 stack = [];
6261 break;
6262 }
6263 }
6264
6265 if (token.type)
6266 tokens.push(token);
6267
6268 if (stack.length > 1) {
6269 if (stack[0] !== currentState)
6270 stack.unshift("#tmp", currentState);
6271 }
6272 return {
6273 tokens : tokens,
6274 state : stack.length ? stack : currentState
6275 };
6276 };
6277
6278 this.reportError = config.reportError;
6279
6280}).call(Tokenizer.prototype);
6281
6282exports.Tokenizer = Tokenizer;
6283});
6284
6285ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"], function(acequire, exports, module) {
6286
6287var lang = acequire("../lib/lang");
6288
6289var TextHighlightRules = function() {
6290
6291 this.$rules = {
6292 "start" : [{
6293 token : "empty_line",
6294 regex : '^$'
6295 }, {
6296 defaultToken : "text"
6297 }]
6298 };
6299};
6300
6301(function() {
6302
6303 this.addRules = function(rules, prefix) {
6304 if (!prefix) {
6305 for (var key in rules)
6306 this.$rules[key] = rules[key];
6307 return;
6308 }
6309 for (var key in rules) {
6310 var state = rules[key];
6311 for (var i = 0; i < state.length; i++) {
6312 var rule = state[i];
6313 if (rule.next || rule.onMatch) {
6314 if (typeof rule.next == "string") {
6315 if (rule.next.indexOf(prefix) !== 0)
6316 rule.next = prefix + rule.next;
6317 }
6318 if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)
6319 rule.nextState = prefix + rule.nextState;
6320 }
6321 }
6322 this.$rules[prefix + key] = state;
6323 }
6324 };
6325
6326 this.getRules = function() {
6327 return this.$rules;
6328 };
6329
6330 this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
6331 var embedRules = typeof HighlightRules == "function"
6332 ? new HighlightRules().getRules()
6333 : HighlightRules;
6334 if (states) {
6335 for (var i = 0; i < states.length; i++)
6336 states[i] = prefix + states[i];
6337 } else {
6338 states = [];
6339 for (var key in embedRules)
6340 states.push(prefix + key);
6341 }
6342
6343 this.addRules(embedRules, prefix);
6344
6345 if (escapeRules) {
6346 var addRules = Array.prototype[append ? "push" : "unshift"];
6347 for (var i = 0; i < states.length; i++)
6348 addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
6349 }
6350
6351 if (!this.$embeds)
6352 this.$embeds = [];
6353 this.$embeds.push(prefix);
6354 };
6355
6356 this.getEmbeds = function() {
6357 return this.$embeds;
6358 };
6359
6360 var pushState = function(currentState, stack) {
6361 if (currentState != "start" || stack.length)
6362 stack.unshift(this.nextState, currentState);
6363 return this.nextState;
6364 };
6365 var popState = function(currentState, stack) {
6366 stack.shift();
6367 return stack.shift() || "start";
6368 };
6369
6370 this.normalizeRules = function() {
6371 var id = 0;
6372 var rules = this.$rules;
6373 function processState(key) {
6374 var state = rules[key];
6375 state.processed = true;
6376 for (var i = 0; i < state.length; i++) {
6377 var rule = state[i];
6378 var toInsert = null;
6379 if (Array.isArray(rule)) {
6380 toInsert = rule;
6381 rule = {};
6382 }
6383 if (!rule.regex && rule.start) {
6384 rule.regex = rule.start;
6385 if (!rule.next)
6386 rule.next = [];
6387 rule.next.push({
6388 defaultToken: rule.token
6389 }, {
6390 token: rule.token + ".end",
6391 regex: rule.end || rule.start,
6392 next: "pop"
6393 });
6394 rule.token = rule.token + ".start";
6395 rule.push = true;
6396 }
6397 var next = rule.next || rule.push;
6398 if (next && Array.isArray(next)) {
6399 var stateName = rule.stateName;
6400 if (!stateName) {
6401 stateName = rule.token;
6402 if (typeof stateName != "string")
6403 stateName = stateName[0] || "";
6404 if (rules[stateName])
6405 stateName += id++;
6406 }
6407 rules[stateName] = next;
6408 rule.next = stateName;
6409 processState(stateName);
6410 } else if (next == "pop") {
6411 rule.next = popState;
6412 }
6413
6414 if (rule.push) {
6415 rule.nextState = rule.next || rule.push;
6416 rule.next = pushState;
6417 delete rule.push;
6418 }
6419
6420 if (rule.rules) {
6421 for (var r in rule.rules) {
6422 if (rules[r]) {
6423 if (rules[r].push)
6424 rules[r].push.apply(rules[r], rule.rules[r]);
6425 } else {
6426 rules[r] = rule.rules[r];
6427 }
6428 }
6429 }
6430 var includeName = typeof rule == "string" ? rule : rule.include;
6431 if (includeName) {
6432 if (Array.isArray(includeName))
6433 toInsert = includeName.map(function(x) { return rules[x]; });
6434 else
6435 toInsert = rules[includeName];
6436 }
6437
6438 if (toInsert) {
6439 var args = [i, 1].concat(toInsert);
6440 if (rule.noEscape)
6441 args = args.filter(function(x) {return !x.next;});
6442 state.splice.apply(state, args);
6443 i--;
6444 }
6445
6446 if (rule.keywordMap) {
6447 rule.token = this.createKeywordMapper(
6448 rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive
6449 );
6450 delete rule.defaultToken;
6451 }
6452 }
6453 }
6454 Object.keys(rules).forEach(processState, this);
6455 };
6456
6457 this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
6458 var keywords = Object.create(null);
6459 Object.keys(map).forEach(function(className) {
6460 var a = map[className];
6461 if (ignoreCase)
6462 a = a.toLowerCase();
6463 var list = a.split(splitChar || "|");
6464 for (var i = list.length; i--; )
6465 keywords[list[i]] = className;
6466 });
6467 if (Object.getPrototypeOf(keywords)) {
6468 keywords.__proto__ = null;
6469 }
6470 this.$keywordList = Object.keys(keywords);
6471 map = null;
6472 return ignoreCase
6473 ? function(value) {return keywords[value.toLowerCase()] || defaultToken; }
6474 : function(value) {return keywords[value] || defaultToken; };
6475 };
6476
6477 this.getKeywords = function() {
6478 return this.$keywords;
6479 };
6480
6481}).call(TextHighlightRules.prototype);
6482
6483exports.TextHighlightRules = TextHighlightRules;
6484});
6485
6486ace.define("ace/mode/behaviour",["require","exports","module"], function(acequire, exports, module) {
6487
6488var Behaviour = function() {
6489 this.$behaviours = {};
6490};
6491
6492(function () {
6493
6494 this.add = function (name, action, callback) {
6495 switch (undefined) {
6496 case this.$behaviours:
6497 this.$behaviours = {};
6498 case this.$behaviours[name]:
6499 this.$behaviours[name] = {};
6500 }
6501 this.$behaviours[name][action] = callback;
6502 };
6503
6504 this.addBehaviours = function (behaviours) {
6505 for (var key in behaviours) {
6506 for (var action in behaviours[key]) {
6507 this.add(key, action, behaviours[key][action]);
6508 }
6509 }
6510 };
6511
6512 this.remove = function (name) {
6513 if (this.$behaviours && this.$behaviours[name]) {
6514 delete this.$behaviours[name];
6515 }
6516 };
6517
6518 this.inherit = function (mode, filter) {
6519 if (typeof mode === "function") {
6520 var behaviours = new mode().getBehaviours(filter);
6521 } else {
6522 var behaviours = mode.getBehaviours(filter);
6523 }
6524 this.addBehaviours(behaviours);
6525 };
6526
6527 this.getBehaviours = function (filter) {
6528 if (!filter) {
6529 return this.$behaviours;
6530 } else {
6531 var ret = {};
6532 for (var i = 0; i < filter.length; i++) {
6533 if (this.$behaviours[filter[i]]) {
6534 ret[filter[i]] = this.$behaviours[filter[i]];
6535 }
6536 }
6537 return ret;
6538 }
6539 };
6540
6541}).call(Behaviour.prototype);
6542
6543exports.Behaviour = Behaviour;
6544});
6545
6546ace.define("ace/token_iterator",["require","exports","module","ace/range"], function(acequire, exports, module) {
6547
6548var Range = acequire("./range").Range;
6549var TokenIterator = function(session, initialRow, initialColumn) {
6550 this.$session = session;
6551 this.$row = initialRow;
6552 this.$rowTokens = session.getTokens(initialRow);
6553
6554 var token = session.getTokenAt(initialRow, initialColumn);
6555 this.$tokenIndex = token ? token.index : -1;
6556};
6557
6558(function() {
6559 this.stepBackward = function() {
6560 this.$tokenIndex -= 1;
6561
6562 while (this.$tokenIndex < 0) {
6563 this.$row -= 1;
6564 if (this.$row < 0) {
6565 this.$row = 0;
6566 return null;
6567 }
6568
6569 this.$rowTokens = this.$session.getTokens(this.$row);
6570 this.$tokenIndex = this.$rowTokens.length - 1;
6571 }
6572
6573 return this.$rowTokens[this.$tokenIndex];
6574 };
6575 this.stepForward = function() {
6576 this.$tokenIndex += 1;
6577 var rowCount;
6578 while (this.$tokenIndex >= this.$rowTokens.length) {
6579 this.$row += 1;
6580 if (!rowCount)
6581 rowCount = this.$session.getLength();
6582 if (this.$row >= rowCount) {
6583 this.$row = rowCount - 1;
6584 return null;
6585 }
6586
6587 this.$rowTokens = this.$session.getTokens(this.$row);
6588 this.$tokenIndex = 0;
6589 }
6590
6591 return this.$rowTokens[this.$tokenIndex];
6592 };
6593 this.getCurrentToken = function () {
6594 return this.$rowTokens[this.$tokenIndex];
6595 };
6596 this.getCurrentTokenRow = function () {
6597 return this.$row;
6598 };
6599 this.getCurrentTokenColumn = function() {
6600 var rowTokens = this.$rowTokens;
6601 var tokenIndex = this.$tokenIndex;
6602 var column = rowTokens[tokenIndex].start;
6603 if (column !== undefined)
6604 return column;
6605
6606 column = 0;
6607 while (tokenIndex > 0) {
6608 tokenIndex -= 1;
6609 column += rowTokens[tokenIndex].value.length;
6610 }
6611
6612 return column;
6613 };
6614 this.getCurrentTokenPosition = function() {
6615 return {row: this.$row, column: this.getCurrentTokenColumn()};
6616 };
6617 this.getCurrentTokenRange = function() {
6618 var token = this.$rowTokens[this.$tokenIndex];
6619 var column = this.getCurrentTokenColumn();
6620 return new Range(this.$row, column, this.$row, column + token.value.length);
6621 };
6622
6623}).call(TokenIterator.prototype);
6624
6625exports.TokenIterator = TokenIterator;
6626});
6627
6628ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(acequire, exports, module) {
6629
6630var oop = acequire("../../lib/oop");
6631var Behaviour = acequire("../behaviour").Behaviour;
6632var TokenIterator = acequire("../../token_iterator").TokenIterator;
6633var lang = acequire("../../lib/lang");
6634
6635var SAFE_INSERT_IN_TOKENS =
6636 ["text", "paren.rparen", "punctuation.operator"];
6637var SAFE_INSERT_BEFORE_TOKENS =
6638 ["text", "paren.rparen", "punctuation.operator", "comment"];
6639
6640var context;
6641var contextCache = {};
6642var defaultQuotes = {'"' : '"', "'" : "'"};
6643
6644var initContext = function(editor) {
6645 var id = -1;
6646 if (editor.multiSelect) {
6647 id = editor.selection.index;
6648 if (contextCache.rangeCount != editor.multiSelect.rangeCount)
6649 contextCache = {rangeCount: editor.multiSelect.rangeCount};
6650 }
6651 if (contextCache[id])
6652 return context = contextCache[id];
6653 context = contextCache[id] = {
6654 autoInsertedBrackets: 0,
6655 autoInsertedRow: -1,
6656 autoInsertedLineEnd: "",
6657 maybeInsertedBrackets: 0,
6658 maybeInsertedRow: -1,
6659 maybeInsertedLineStart: "",
6660 maybeInsertedLineEnd: ""
6661 };
6662};
6663
6664var getWrapped = function(selection, selected, opening, closing) {
6665 var rowDiff = selection.end.row - selection.start.row;
6666 return {
6667 text: opening + selected + closing,
6668 selection: [
6669 0,
6670 selection.start.column + 1,
6671 rowDiff,
6672 selection.end.column + (rowDiff ? 0 : 1)
6673 ]
6674 };
6675};
6676
6677var CstyleBehaviour = function(options) {
6678 this.add("braces", "insertion", function(state, action, editor, session, text) {
6679 var cursor = editor.getCursorPosition();
6680 var line = session.doc.getLine(cursor.row);
6681 if (text == '{') {
6682 initContext(editor);
6683 var selection = editor.getSelectionRange();
6684 var selected = session.doc.getTextRange(selection);
6685 if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
6686 return getWrapped(selection, selected, '{', '}');
6687 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6688 if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) {
6689 CstyleBehaviour.recordAutoInsert(editor, session, "}");
6690 return {
6691 text: '{}',
6692 selection: [1, 1]
6693 };
6694 } else {
6695 CstyleBehaviour.recordMaybeInsert(editor, session, "{");
6696 return {
6697 text: '{',
6698 selection: [1, 1]
6699 };
6700 }
6701 }
6702 } else if (text == '}') {
6703 initContext(editor);
6704 var rightChar = line.substring(cursor.column, cursor.column + 1);
6705 if (rightChar == '}') {
6706 var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
6707 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6708 CstyleBehaviour.popAutoInsertedClosing();
6709 return {
6710 text: '',
6711 selection: [1, 1]
6712 };
6713 }
6714 }
6715 } else if (text == "\n" || text == "\r\n") {
6716 initContext(editor);
6717 var closing = "";
6718 if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
6719 closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
6720 CstyleBehaviour.clearMaybeInsertedClosing();
6721 }
6722 var rightChar = line.substring(cursor.column, cursor.column + 1);
6723 if (rightChar === '}') {
6724 var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
6725 if (!openBracePos)
6726 return null;
6727 var next_indent = this.$getIndent(session.getLine(openBracePos.row));
6728 } else if (closing) {
6729 var next_indent = this.$getIndent(line);
6730 } else {
6731 CstyleBehaviour.clearMaybeInsertedClosing();
6732 return;
6733 }
6734 var indent = next_indent + session.getTabString();
6735
6736 return {
6737 text: '\n' + indent + '\n' + next_indent + closing,
6738 selection: [1, indent.length, 1, indent.length]
6739 };
6740 } else {
6741 CstyleBehaviour.clearMaybeInsertedClosing();
6742 }
6743 });
6744
6745 this.add("braces", "deletion", function(state, action, editor, session, range) {
6746 var selected = session.doc.getTextRange(range);
6747 if (!range.isMultiLine() && selected == '{') {
6748 initContext(editor);
6749 var line = session.doc.getLine(range.start.row);
6750 var rightChar = line.substring(range.end.column, range.end.column + 1);
6751 if (rightChar == '}') {
6752 range.end.column++;
6753 return range;
6754 } else {
6755 context.maybeInsertedBrackets--;
6756 }
6757 }
6758 });
6759
6760 this.add("parens", "insertion", function(state, action, editor, session, text) {
6761 if (text == '(') {
6762 initContext(editor);
6763 var selection = editor.getSelectionRange();
6764 var selected = session.doc.getTextRange(selection);
6765 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
6766 return getWrapped(selection, selected, '(', ')');
6767 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6768 CstyleBehaviour.recordAutoInsert(editor, session, ")");
6769 return {
6770 text: '()',
6771 selection: [1, 1]
6772 };
6773 }
6774 } else if (text == ')') {
6775 initContext(editor);
6776 var cursor = editor.getCursorPosition();
6777 var line = session.doc.getLine(cursor.row);
6778 var rightChar = line.substring(cursor.column, cursor.column + 1);
6779 if (rightChar == ')') {
6780 var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
6781 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6782 CstyleBehaviour.popAutoInsertedClosing();
6783 return {
6784 text: '',
6785 selection: [1, 1]
6786 };
6787 }
6788 }
6789 }
6790 });
6791
6792 this.add("parens", "deletion", function(state, action, editor, session, range) {
6793 var selected = session.doc.getTextRange(range);
6794 if (!range.isMultiLine() && selected == '(') {
6795 initContext(editor);
6796 var line = session.doc.getLine(range.start.row);
6797 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6798 if (rightChar == ')') {
6799 range.end.column++;
6800 return range;
6801 }
6802 }
6803 });
6804
6805 this.add("brackets", "insertion", function(state, action, editor, session, text) {
6806 if (text == '[') {
6807 initContext(editor);
6808 var selection = editor.getSelectionRange();
6809 var selected = session.doc.getTextRange(selection);
6810 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
6811 return getWrapped(selection, selected, '[', ']');
6812 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6813 CstyleBehaviour.recordAutoInsert(editor, session, "]");
6814 return {
6815 text: '[]',
6816 selection: [1, 1]
6817 };
6818 }
6819 } else if (text == ']') {
6820 initContext(editor);
6821 var cursor = editor.getCursorPosition();
6822 var line = session.doc.getLine(cursor.row);
6823 var rightChar = line.substring(cursor.column, cursor.column + 1);
6824 if (rightChar == ']') {
6825 var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
6826 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6827 CstyleBehaviour.popAutoInsertedClosing();
6828 return {
6829 text: '',
6830 selection: [1, 1]
6831 };
6832 }
6833 }
6834 }
6835 });
6836
6837 this.add("brackets", "deletion", function(state, action, editor, session, range) {
6838 var selected = session.doc.getTextRange(range);
6839 if (!range.isMultiLine() && selected == '[') {
6840 initContext(editor);
6841 var line = session.doc.getLine(range.start.row);
6842 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6843 if (rightChar == ']') {
6844 range.end.column++;
6845 return range;
6846 }
6847 }
6848 });
6849
6850 this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
6851 var quotes = session.$mode.$quotes || defaultQuotes;
6852 if (text.length == 1 && quotes[text]) {
6853 if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1)
6854 return;
6855 initContext(editor);
6856 var quote = text;
6857 var selection = editor.getSelectionRange();
6858 var selected = session.doc.getTextRange(selection);
6859 if (selected !== "" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) {
6860 return getWrapped(selection, selected, quote, quote);
6861 } else if (!selected) {
6862 var cursor = editor.getCursorPosition();
6863 var line = session.doc.getLine(cursor.row);
6864 var leftChar = line.substring(cursor.column-1, cursor.column);
6865 var rightChar = line.substring(cursor.column, cursor.column + 1);
6866
6867 var token = session.getTokenAt(cursor.row, cursor.column);
6868 var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);
6869 if (leftChar == "\\" && token && /escape/.test(token.type))
6870 return null;
6871
6872 var stringBefore = token && /string|escape/.test(token.type);
6873 var stringAfter = !rightToken || /string|escape/.test(rightToken.type);
6874
6875 var pair;
6876 if (rightChar == quote) {
6877 pair = stringBefore !== stringAfter;
6878 if (pair && /string\.end/.test(rightToken.type))
6879 pair = false;
6880 } else {
6881 if (stringBefore && !stringAfter)
6882 return null; // wrap string with different quote
6883 if (stringBefore && stringAfter)
6884 return null; // do not pair quotes inside strings
6885 var wordRe = session.$mode.tokenRe;
6886 wordRe.lastIndex = 0;
6887 var isWordBefore = wordRe.test(leftChar);
6888 wordRe.lastIndex = 0;
6889 var isWordAfter = wordRe.test(leftChar);
6890 if (isWordBefore || isWordAfter)
6891 return null; // before or after alphanumeric
6892 if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
6893 return null; // there is rightChar and it isn't closing
6894 pair = true;
6895 }
6896 return {
6897 text: pair ? quote + quote : "",
6898 selection: [1,1]
6899 };
6900 }
6901 }
6902 });
6903
6904 this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
6905 var selected = session.doc.getTextRange(range);
6906 if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
6907 initContext(editor);
6908 var line = session.doc.getLine(range.start.row);
6909 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6910 if (rightChar == selected) {
6911 range.end.column++;
6912 return range;
6913 }
6914 }
6915 });
6916
6917};
6918
6919
6920CstyleBehaviour.isSaneInsertion = function(editor, session) {
6921 var cursor = editor.getCursorPosition();
6922 var iterator = new TokenIterator(session, cursor.row, cursor.column);
6923 if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
6924 var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
6925 if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
6926 return false;
6927 }
6928 iterator.stepForward();
6929 return iterator.getCurrentTokenRow() !== cursor.row ||
6930 this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
6931};
6932
6933CstyleBehaviour.$matchTokenType = function(token, types) {
6934 return types.indexOf(token.type || token) > -1;
6935};
6936
6937CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
6938 var cursor = editor.getCursorPosition();
6939 var line = session.doc.getLine(cursor.row);
6940 if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
6941 context.autoInsertedBrackets = 0;
6942 context.autoInsertedRow = cursor.row;
6943 context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
6944 context.autoInsertedBrackets++;
6945};
6946
6947CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
6948 var cursor = editor.getCursorPosition();
6949 var line = session.doc.getLine(cursor.row);
6950 if (!this.isMaybeInsertedClosing(cursor, line))
6951 context.maybeInsertedBrackets = 0;
6952 context.maybeInsertedRow = cursor.row;
6953 context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
6954 context.maybeInsertedLineEnd = line.substr(cursor.column);
6955 context.maybeInsertedBrackets++;
6956};
6957
6958CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
6959 return context.autoInsertedBrackets > 0 &&
6960 cursor.row === context.autoInsertedRow &&
6961 bracket === context.autoInsertedLineEnd[0] &&
6962 line.substr(cursor.column) === context.autoInsertedLineEnd;
6963};
6964
6965CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
6966 return context.maybeInsertedBrackets > 0 &&
6967 cursor.row === context.maybeInsertedRow &&
6968 line.substr(cursor.column) === context.maybeInsertedLineEnd &&
6969 line.substr(0, cursor.column) == context.maybeInsertedLineStart;
6970};
6971
6972CstyleBehaviour.popAutoInsertedClosing = function() {
6973 context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
6974 context.autoInsertedBrackets--;
6975};
6976
6977CstyleBehaviour.clearMaybeInsertedClosing = function() {
6978 if (context) {
6979 context.maybeInsertedBrackets = 0;
6980 context.maybeInsertedRow = -1;
6981 }
6982};
6983
6984
6985
6986oop.inherits(CstyleBehaviour, Behaviour);
6987
6988exports.CstyleBehaviour = CstyleBehaviour;
6989});
6990
6991ace.define("ace/unicode",["require","exports","module"], function(acequire, exports, module) {
6992exports.packages = {};
6993
6994addUnicodePackage({
6995 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",
6996 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",
6997 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",
6998 Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",
6999 Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",
7000 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",
7001 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",
7002 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",
7003 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",
7004 Me: "0488048906DE20DD-20E020E2-20E4A670-A672",
7005 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",
7006 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",
7007 Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",
7008 No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",
7009 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",
7010 Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",
7011 Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",
7012 Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",
7013 Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",
7014 Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21",
7015 Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F",
7016 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",
7017 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",
7018 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",
7019 Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",
7020 Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",
7021 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",
7022 Z: "002000A01680180E2000-200A20282029202F205F3000",
7023 Zs: "002000A01680180E2000-200A202F205F3000",
7024 Zl: "2028",
7025 Zp: "2029",
7026 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",
7027 Cc: "0000-001F007F-009F",
7028 Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",
7029 Co: "E000-F8FF",
7030 Cs: "D800-DFFF",
7031 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"
7032});
7033
7034function addUnicodePackage (pack) {
7035 var codePoint = /\w{4}/g;
7036 for (var name in pack)
7037 exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
7038}
7039
7040});
7041
7042ace.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) {
7043
7044var Tokenizer = acequire("../tokenizer").Tokenizer;
7045var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
7046var CstyleBehaviour = acequire("./behaviour/cstyle").CstyleBehaviour;
7047var unicode = acequire("../unicode");
7048var lang = acequire("../lib/lang");
7049var TokenIterator = acequire("../token_iterator").TokenIterator;
7050var Range = acequire("../range").Range;
7051
7052var Mode = function() {
7053 this.HighlightRules = TextHighlightRules;
7054};
7055
7056(function() {
7057 this.$defaultBehaviour = new CstyleBehaviour();
7058
7059 this.tokenRe = new RegExp("^["
7060 + unicode.packages.L
7061 + unicode.packages.Mn + unicode.packages.Mc
7062 + unicode.packages.Nd
7063 + unicode.packages.Pc + "\\$_]+", "g"
7064 );
7065
7066 this.nonTokenRe = new RegExp("^(?:[^"
7067 + unicode.packages.L
7068 + unicode.packages.Mn + unicode.packages.Mc
7069 + unicode.packages.Nd
7070 + unicode.packages.Pc + "\\$_]|\\s])+", "g"
7071 );
7072
7073 this.getTokenizer = function() {
7074 if (!this.$tokenizer) {
7075 this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig);
7076 this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());
7077 }
7078 return this.$tokenizer;
7079 };
7080
7081 this.lineCommentStart = "";
7082 this.blockComment = "";
7083
7084 this.toggleCommentLines = function(state, session, startRow, endRow) {
7085 var doc = session.doc;
7086
7087 var ignoreBlankLines = true;
7088 var shouldRemove = true;
7089 var minIndent = Infinity;
7090 var tabSize = session.getTabSize();
7091 var insertAtTabStop = false;
7092
7093 if (!this.lineCommentStart) {
7094 if (!this.blockComment)
7095 return false;
7096 var lineCommentStart = this.blockComment.start;
7097 var lineCommentEnd = this.blockComment.end;
7098 var regexpStart = new RegExp("^(\\s*)(?:" + lang.escapeRegExp(lineCommentStart) + ")");
7099 var regexpEnd = new RegExp("(?:" + lang.escapeRegExp(lineCommentEnd) + ")\\s*$");
7100
7101 var comment = function(line, i) {
7102 if (testRemove(line, i))
7103 return;
7104 if (!ignoreBlankLines || /\S/.test(line)) {
7105 doc.insertInLine({row: i, column: line.length}, lineCommentEnd);
7106 doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
7107 }
7108 };
7109
7110 var uncomment = function(line, i) {
7111 var m;
7112 if (m = line.match(regexpEnd))
7113 doc.removeInLine(i, line.length - m[0].length, line.length);
7114 if (m = line.match(regexpStart))
7115 doc.removeInLine(i, m[1].length, m[0].length);
7116 };
7117
7118 var testRemove = function(line, row) {
7119 if (regexpStart.test(line))
7120 return true;
7121 var tokens = session.getTokens(row);
7122 for (var i = 0; i < tokens.length; i++) {
7123 if (tokens[i].type === "comment")
7124 return true;
7125 }
7126 };
7127 } else {
7128 if (Array.isArray(this.lineCommentStart)) {
7129 var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|");
7130 var lineCommentStart = this.lineCommentStart[0];
7131 } else {
7132 var regexpStart = lang.escapeRegExp(this.lineCommentStart);
7133 var lineCommentStart = this.lineCommentStart;
7134 }
7135 regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?");
7136
7137 insertAtTabStop = session.getUseSoftTabs();
7138
7139 var uncomment = function(line, i) {
7140 var m = line.match(regexpStart);
7141 if (!m) return;
7142 var start = m[1].length, end = m[0].length;
7143 if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ")
7144 end--;
7145 doc.removeInLine(i, start, end);
7146 };
7147 var commentWithSpace = lineCommentStart + " ";
7148 var comment = function(line, i) {
7149 if (!ignoreBlankLines || /\S/.test(line)) {
7150 if (shouldInsertSpace(line, minIndent, minIndent))
7151 doc.insertInLine({row: i, column: minIndent}, commentWithSpace);
7152 else
7153 doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
7154 }
7155 };
7156 var testRemove = function(line, i) {
7157 return regexpStart.test(line);
7158 };
7159
7160 var shouldInsertSpace = function(line, before, after) {
7161 var spaces = 0;
7162 while (before-- && line.charAt(before) == " ")
7163 spaces++;
7164 if (spaces % tabSize != 0)
7165 return false;
7166 var spaces = 0;
7167 while (line.charAt(after++) == " ")
7168 spaces++;
7169 if (tabSize > 2)
7170 return spaces % tabSize != tabSize - 1;
7171 else
7172 return spaces % tabSize == 0;
7173 };
7174 }
7175
7176 function iter(fun) {
7177 for (var i = startRow; i <= endRow; i++)
7178 fun(doc.getLine(i), i);
7179 }
7180
7181
7182 var minEmptyLength = Infinity;
7183 iter(function(line, i) {
7184 var indent = line.search(/\S/);
7185 if (indent !== -1) {
7186 if (indent < minIndent)
7187 minIndent = indent;
7188 if (shouldRemove && !testRemove(line, i))
7189 shouldRemove = false;
7190 } else if (minEmptyLength > line.length) {
7191 minEmptyLength = line.length;
7192 }
7193 });
7194
7195 if (minIndent == Infinity) {
7196 minIndent = minEmptyLength;
7197 ignoreBlankLines = false;
7198 shouldRemove = false;
7199 }
7200
7201 if (insertAtTabStop && minIndent % tabSize != 0)
7202 minIndent = Math.floor(minIndent / tabSize) * tabSize;
7203
7204 iter(shouldRemove ? uncomment : comment);
7205 };
7206
7207 this.toggleBlockComment = function(state, session, range, cursor) {
7208 var comment = this.blockComment;
7209 if (!comment)
7210 return;
7211 if (!comment.start && comment[0])
7212 comment = comment[0];
7213
7214 var iterator = new TokenIterator(session, cursor.row, cursor.column);
7215 var token = iterator.getCurrentToken();
7216
7217 session.selection;
7218 var initialRange = session.selection.toOrientedRange();
7219 var startRow, colDiff;
7220
7221 if (token && /comment/.test(token.type)) {
7222 var startRange, endRange;
7223 while (token && /comment/.test(token.type)) {
7224 var i = token.value.indexOf(comment.start);
7225 if (i != -1) {
7226 var row = iterator.getCurrentTokenRow();
7227 var column = iterator.getCurrentTokenColumn() + i;
7228 startRange = new Range(row, column, row, column + comment.start.length);
7229 break;
7230 }
7231 token = iterator.stepBackward();
7232 }
7233
7234 var iterator = new TokenIterator(session, cursor.row, cursor.column);
7235 var token = iterator.getCurrentToken();
7236 while (token && /comment/.test(token.type)) {
7237 var i = token.value.indexOf(comment.end);
7238 if (i != -1) {
7239 var row = iterator.getCurrentTokenRow();
7240 var column = iterator.getCurrentTokenColumn() + i;
7241 endRange = new Range(row, column, row, column + comment.end.length);
7242 break;
7243 }
7244 token = iterator.stepForward();
7245 }
7246 if (endRange)
7247 session.remove(endRange);
7248 if (startRange) {
7249 session.remove(startRange);
7250 startRow = startRange.start.row;
7251 colDiff = -comment.start.length;
7252 }
7253 } else {
7254 colDiff = comment.start.length;
7255 startRow = range.start.row;
7256 session.insert(range.end, comment.end);
7257 session.insert(range.start, comment.start);
7258 }
7259 if (initialRange.start.row == startRow)
7260 initialRange.start.column += colDiff;
7261 if (initialRange.end.row == startRow)
7262 initialRange.end.column += colDiff;
7263 session.selection.fromOrientedRange(initialRange);
7264 };
7265
7266 this.getNextLineIndent = function(state, line, tab) {
7267 return this.$getIndent(line);
7268 };
7269
7270 this.checkOutdent = function(state, line, input) {
7271 return false;
7272 };
7273
7274 this.autoOutdent = function(state, doc, row) {
7275 };
7276
7277 this.$getIndent = function(line) {
7278 return line.match(/^\s*/)[0];
7279 };
7280
7281 this.createWorker = function(session) {
7282 return null;
7283 };
7284
7285 this.createModeDelegates = function (mapping) {
7286 this.$embeds = [];
7287 this.$modes = {};
7288 for (var i in mapping) {
7289 if (mapping[i]) {
7290 this.$embeds.push(i);
7291 this.$modes[i] = new mapping[i]();
7292 }
7293 }
7294
7295 var delegations = ["toggleBlockComment", "toggleCommentLines", "getNextLineIndent",
7296 "checkOutdent", "autoOutdent", "transformAction", "getCompletions"];
7297
7298 for (var i = 0; i < delegations.length; i++) {
7299 (function(scope) {
7300 var functionName = delegations[i];
7301 var defaultHandler = scope[functionName];
7302 scope[delegations[i]] = function() {
7303 return this.$delegator(functionName, arguments, defaultHandler);
7304 };
7305 }(this));
7306 }
7307 };
7308
7309 this.$delegator = function(method, args, defaultHandler) {
7310 var state = args[0];
7311 if (typeof state != "string")
7312 state = state[0];
7313 for (var i = 0; i < this.$embeds.length; i++) {
7314 if (!this.$modes[this.$embeds[i]]) continue;
7315
7316 var split = state.split(this.$embeds[i]);
7317 if (!split[0] && split[1]) {
7318 args[0] = split[1];
7319 var mode = this.$modes[this.$embeds[i]];
7320 return mode[method].apply(mode, args);
7321 }
7322 }
7323 var ret = defaultHandler.apply(this, args);
7324 return defaultHandler ? ret : undefined;
7325 };
7326
7327 this.transformAction = function(state, action, editor, session, param) {
7328 if (this.$behaviour) {
7329 var behaviours = this.$behaviour.getBehaviours();
7330 for (var key in behaviours) {
7331 if (behaviours[key][action]) {
7332 var ret = behaviours[key][action].apply(this, arguments);
7333 if (ret) {
7334 return ret;
7335 }
7336 }
7337 }
7338 }
7339 };
7340
7341 this.getKeywords = function(append) {
7342 if (!this.completionKeywords) {
7343 var rules = this.$tokenizer.rules;
7344 var completionKeywords = [];
7345 for (var rule in rules) {
7346 var ruleItr = rules[rule];
7347 for (var r = 0, l = ruleItr.length; r < l; r++) {
7348 if (typeof ruleItr[r].token === "string") {
7349 if (/keyword|support|storage/.test(ruleItr[r].token))
7350 completionKeywords.push(ruleItr[r].regex);
7351 }
7352 else if (typeof ruleItr[r].token === "object") {
7353 for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {
7354 if (/keyword|support|storage/.test(ruleItr[r].token[a])) {
7355 var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a];
7356 completionKeywords.push(rule.substr(1, rule.length - 2));
7357 }
7358 }
7359 }
7360 }
7361 }
7362 this.completionKeywords = completionKeywords;
7363 }
7364 if (!append)
7365 return this.$keywordList;
7366 return completionKeywords.concat(this.$keywordList || []);
7367 };
7368
7369 this.$createKeywordList = function() {
7370 if (!this.$highlightRules)
7371 this.getTokenizer();
7372 return this.$keywordList = this.$highlightRules.$keywordList || [];
7373 };
7374
7375 this.getCompletions = function(state, session, pos, prefix) {
7376 var keywords = this.$keywordList || this.$createKeywordList();
7377 return keywords.map(function(word) {
7378 return {
7379 name: word,
7380 value: word,
7381 score: 0,
7382 meta: "keyword"
7383 };
7384 });
7385 };
7386
7387 this.$id = "ace/mode/text";
7388}).call(Mode.prototype);
7389
7390exports.Mode = Mode;
7391});
7392
7393ace.define("ace/apply_delta",["require","exports","module"], function(acequire, exports, module) {
7394
7395exports.applyDelta = function(docLines, delta, doNotValidate) {
7396
7397 var row = delta.start.row;
7398 var startColumn = delta.start.column;
7399 var line = docLines[row] || "";
7400 switch (delta.action) {
7401 case "insert":
7402 var lines = delta.lines;
7403 if (lines.length === 1) {
7404 docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
7405 } else {
7406 var args = [row, 1].concat(delta.lines);
7407 docLines.splice.apply(docLines, args);
7408 docLines[row] = line.substring(0, startColumn) + docLines[row];
7409 docLines[row + delta.lines.length - 1] += line.substring(startColumn);
7410 }
7411 break;
7412 case "remove":
7413 var endColumn = delta.end.column;
7414 var endRow = delta.end.row;
7415 if (row === endRow) {
7416 docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);
7417 } else {
7418 docLines.splice(
7419 row, endRow - row + 1,
7420 line.substring(0, startColumn) + docLines[endRow].substring(endColumn)
7421 );
7422 }
7423 break;
7424 }
7425};
7426});
7427
7428ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(acequire, exports, module) {
7429
7430var oop = acequire("./lib/oop");
7431var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
7432
7433var Anchor = exports.Anchor = function(doc, row, column) {
7434 this.$onChange = this.onChange.bind(this);
7435 this.attach(doc);
7436
7437 if (typeof column == "undefined")
7438 this.setPosition(row.row, row.column);
7439 else
7440 this.setPosition(row, column);
7441};
7442
7443(function() {
7444
7445 oop.implement(this, EventEmitter);
7446 this.getPosition = function() {
7447 return this.$clipPositionToDocument(this.row, this.column);
7448 };
7449 this.getDocument = function() {
7450 return this.document;
7451 };
7452 this.$insertRight = false;
7453 this.onChange = function(delta) {
7454 if (delta.start.row == delta.end.row && delta.start.row != this.row)
7455 return;
7456
7457 if (delta.start.row > this.row)
7458 return;
7459
7460 var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);
7461 this.setPosition(point.row, point.column, true);
7462 };
7463
7464 function $pointsInOrder(point1, point2, equalPointsInOrder) {
7465 var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;
7466 return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);
7467 }
7468
7469 function $getTransformedPoint(delta, point, moveIfEqual) {
7470 var deltaIsInsert = delta.action == "insert";
7471 var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row);
7472 var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);
7473 var deltaStart = delta.start;
7474 var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.
7475 if ($pointsInOrder(point, deltaStart, moveIfEqual)) {
7476 return {
7477 row: point.row,
7478 column: point.column
7479 };
7480 }
7481 if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {
7482 return {
7483 row: point.row + deltaRowShift,
7484 column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)
7485 };
7486 }
7487
7488 return {
7489 row: deltaStart.row,
7490 column: deltaStart.column
7491 };
7492 }
7493 this.setPosition = function(row, column, noClip) {
7494 var pos;
7495 if (noClip) {
7496 pos = {
7497 row: row,
7498 column: column
7499 };
7500 } else {
7501 pos = this.$clipPositionToDocument(row, column);
7502 }
7503
7504 if (this.row == pos.row && this.column == pos.column)
7505 return;
7506
7507 var old = {
7508 row: this.row,
7509 column: this.column
7510 };
7511
7512 this.row = pos.row;
7513 this.column = pos.column;
7514 this._signal("change", {
7515 old: old,
7516 value: pos
7517 });
7518 };
7519 this.detach = function() {
7520 this.document.removeEventListener("change", this.$onChange);
7521 };
7522 this.attach = function(doc) {
7523 this.document = doc || this.document;
7524 this.document.on("change", this.$onChange);
7525 };
7526 this.$clipPositionToDocument = function(row, column) {
7527 var pos = {};
7528
7529 if (row >= this.document.getLength()) {
7530 pos.row = Math.max(0, this.document.getLength() - 1);
7531 pos.column = this.document.getLine(pos.row).length;
7532 }
7533 else if (row < 0) {
7534 pos.row = 0;
7535 pos.column = 0;
7536 }
7537 else {
7538 pos.row = row;
7539 pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
7540 }
7541
7542 if (column < 0)
7543 pos.column = 0;
7544
7545 return pos;
7546 };
7547
7548}).call(Anchor.prototype);
7549
7550});
7551
7552ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"], function(acequire, exports, module) {
7553
7554var oop = acequire("./lib/oop");
7555var applyDelta = acequire("./apply_delta").applyDelta;
7556var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
7557var Range = acequire("./range").Range;
7558var Anchor = acequire("./anchor").Anchor;
7559
7560var Document = function(textOrLines) {
7561 this.$lines = [""];
7562 if (textOrLines.length === 0) {
7563 this.$lines = [""];
7564 } else if (Array.isArray(textOrLines)) {
7565 this.insertMergedLines({row: 0, column: 0}, textOrLines);
7566 } else {
7567 this.insert({row: 0, column:0}, textOrLines);
7568 }
7569};
7570
7571(function() {
7572
7573 oop.implement(this, EventEmitter);
7574 this.setValue = function(text) {
7575 var len = this.getLength() - 1;
7576 this.remove(new Range(0, 0, len, this.getLine(len).length));
7577 this.insert({row: 0, column: 0}, text);
7578 };
7579 this.getValue = function() {
7580 return this.getAllLines().join(this.getNewLineCharacter());
7581 };
7582 this.createAnchor = function(row, column) {
7583 return new Anchor(this, row, column);
7584 };
7585 if ("aaa".split(/a/).length === 0) {
7586 this.$split = function(text) {
7587 return text.replace(/\r\n|\r/g, "\n").split("\n");
7588 };
7589 } else {
7590 this.$split = function(text) {
7591 return text.split(/\r\n|\r|\n/);
7592 };
7593 }
7594
7595
7596 this.$detectNewLine = function(text) {
7597 var match = text.match(/^.*?(\r\n|\r|\n)/m);
7598 this.$autoNewLine = match ? match[1] : "\n";
7599 this._signal("changeNewLineMode");
7600 };
7601 this.getNewLineCharacter = function() {
7602 switch (this.$newLineMode) {
7603 case "windows":
7604 return "\r\n";
7605 case "unix":
7606 return "\n";
7607 default:
7608 return this.$autoNewLine || "\n";
7609 }
7610 };
7611
7612 this.$autoNewLine = "";
7613 this.$newLineMode = "auto";
7614 this.setNewLineMode = function(newLineMode) {
7615 if (this.$newLineMode === newLineMode)
7616 return;
7617
7618 this.$newLineMode = newLineMode;
7619 this._signal("changeNewLineMode");
7620 };
7621 this.getNewLineMode = function() {
7622 return this.$newLineMode;
7623 };
7624 this.isNewLine = function(text) {
7625 return (text == "\r\n" || text == "\r" || text == "\n");
7626 };
7627 this.getLine = function(row) {
7628 return this.$lines[row] || "";
7629 };
7630 this.getLines = function(firstRow, lastRow) {
7631 return this.$lines.slice(firstRow, lastRow + 1);
7632 };
7633 this.getAllLines = function() {
7634 return this.getLines(0, this.getLength());
7635 };
7636 this.getLength = function() {
7637 return this.$lines.length;
7638 };
7639 this.getTextRange = function(range) {
7640 return this.getLinesForRange(range).join(this.getNewLineCharacter());
7641 };
7642 this.getLinesForRange = function(range) {
7643 var lines;
7644 if (range.start.row === range.end.row) {
7645 lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];
7646 } else {
7647 lines = this.getLines(range.start.row, range.end.row);
7648 lines[0] = (lines[0] || "").substring(range.start.column);
7649 var l = lines.length - 1;
7650 if (range.end.row - range.start.row == l)
7651 lines[l] = lines[l].substring(0, range.end.column);
7652 }
7653 return lines;
7654 };
7655 this.insertLines = function(row, lines) {
7656 console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead.");
7657 return this.insertFullLines(row, lines);
7658 };
7659 this.removeLines = function(firstRow, lastRow) {
7660 console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead.");
7661 return this.removeFullLines(firstRow, lastRow);
7662 };
7663 this.insertNewLine = function(position) {
7664 console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.");
7665 return this.insertMergedLines(position, ["", ""]);
7666 };
7667 this.insert = function(position, text) {
7668 if (this.getLength() <= 1)
7669 this.$detectNewLine(text);
7670
7671 return this.insertMergedLines(position, this.$split(text));
7672 };
7673 this.insertInLine = function(position, text) {
7674 var start = this.clippedPos(position.row, position.column);
7675 var end = this.pos(position.row, position.column + text.length);
7676
7677 this.applyDelta({
7678 start: start,
7679 end: end,
7680 action: "insert",
7681 lines: [text]
7682 }, true);
7683
7684 return this.clonePos(end);
7685 };
7686
7687 this.clippedPos = function(row, column) {
7688 var length = this.getLength();
7689 if (row === undefined) {
7690 row = length;
7691 } else if (row < 0) {
7692 row = 0;
7693 } else if (row >= length) {
7694 row = length - 1;
7695 column = undefined;
7696 }
7697 var line = this.getLine(row);
7698 if (column == undefined)
7699 column = line.length;
7700 column = Math.min(Math.max(column, 0), line.length);
7701 return {row: row, column: column};
7702 };
7703
7704 this.clonePos = function(pos) {
7705 return {row: pos.row, column: pos.column};
7706 };
7707
7708 this.pos = function(row, column) {
7709 return {row: row, column: column};
7710 };
7711
7712 this.$clipPosition = function(position) {
7713 var length = this.getLength();
7714 if (position.row >= length) {
7715 position.row = Math.max(0, length - 1);
7716 position.column = this.getLine(length - 1).length;
7717 } else {
7718 position.row = Math.max(0, position.row);
7719 position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);
7720 }
7721 return position;
7722 };
7723 this.insertFullLines = function(row, lines) {
7724 row = Math.min(Math.max(row, 0), this.getLength());
7725 var column = 0;
7726 if (row < this.getLength()) {
7727 lines = lines.concat([""]);
7728 column = 0;
7729 } else {
7730 lines = [""].concat(lines);
7731 row--;
7732 column = this.$lines[row].length;
7733 }
7734 this.insertMergedLines({row: row, column: column}, lines);
7735 };
7736 this.insertMergedLines = function(position, lines) {
7737 var start = this.clippedPos(position.row, position.column);
7738 var end = {
7739 row: start.row + lines.length - 1,
7740 column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length
7741 };
7742
7743 this.applyDelta({
7744 start: start,
7745 end: end,
7746 action: "insert",
7747 lines: lines
7748 });
7749
7750 return this.clonePos(end);
7751 };
7752 this.remove = function(range) {
7753 var start = this.clippedPos(range.start.row, range.start.column);
7754 var end = this.clippedPos(range.end.row, range.end.column);
7755 this.applyDelta({
7756 start: start,
7757 end: end,
7758 action: "remove",
7759 lines: this.getLinesForRange({start: start, end: end})
7760 });
7761 return this.clonePos(start);
7762 };
7763 this.removeInLine = function(row, startColumn, endColumn) {
7764 var start = this.clippedPos(row, startColumn);
7765 var end = this.clippedPos(row, endColumn);
7766
7767 this.applyDelta({
7768 start: start,
7769 end: end,
7770 action: "remove",
7771 lines: this.getLinesForRange({start: start, end: end})
7772 }, true);
7773
7774 return this.clonePos(start);
7775 };
7776 this.removeFullLines = function(firstRow, lastRow) {
7777 firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);
7778 lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1);
7779 var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;
7780 var deleteLastNewLine = lastRow < this.getLength() - 1;
7781 var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow );
7782 var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 );
7783 var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow );
7784 var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length );
7785 var range = new Range(startRow, startCol, endRow, endCol);
7786 var deletedLines = this.$lines.slice(firstRow, lastRow + 1);
7787
7788 this.applyDelta({
7789 start: range.start,
7790 end: range.end,
7791 action: "remove",
7792 lines: this.getLinesForRange(range)
7793 });
7794 return deletedLines;
7795 };
7796 this.removeNewLine = function(row) {
7797 if (row < this.getLength() - 1 && row >= 0) {
7798 this.applyDelta({
7799 start: this.pos(row, this.getLine(row).length),
7800 end: this.pos(row + 1, 0),
7801 action: "remove",
7802 lines: ["", ""]
7803 });
7804 }
7805 };
7806 this.replace = function(range, text) {
7807 if (!(range instanceof Range))
7808 range = Range.fromPoints(range.start, range.end);
7809 if (text.length === 0 && range.isEmpty())
7810 return range.start;
7811 if (text == this.getTextRange(range))
7812 return range.end;
7813
7814 this.remove(range);
7815 var end;
7816 if (text) {
7817 end = this.insert(range.start, text);
7818 }
7819 else {
7820 end = range.start;
7821 }
7822
7823 return end;
7824 };
7825 this.applyDeltas = function(deltas) {
7826 for (var i=0; i<deltas.length; i++) {
7827 this.applyDelta(deltas[i]);
7828 }
7829 };
7830 this.revertDeltas = function(deltas) {
7831 for (var i=deltas.length-1; i>=0; i--) {
7832 this.revertDelta(deltas[i]);
7833 }
7834 };
7835 this.applyDelta = function(delta, doNotValidate) {
7836 var isInsert = delta.action == "insert";
7837 if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]
7838 : !Range.comparePoints(delta.start, delta.end)) {
7839 return;
7840 }
7841
7842 if (isInsert && delta.lines.length > 20000)
7843 this.$splitAndapplyLargeDelta(delta, 20000);
7844 applyDelta(this.$lines, delta, doNotValidate);
7845 this._signal("change", delta);
7846 };
7847
7848 this.$splitAndapplyLargeDelta = function(delta, MAX) {
7849 var lines = delta.lines;
7850 var l = lines.length;
7851 var row = delta.start.row;
7852 var column = delta.start.column;
7853 var from = 0, to = 0;
7854 do {
7855 from = to;
7856 to += MAX - 1;
7857 var chunk = lines.slice(from, to);
7858 if (to > l) {
7859 delta.lines = chunk;
7860 delta.start.row = row + from;
7861 delta.start.column = column;
7862 break;
7863 }
7864 chunk.push("");
7865 this.applyDelta({
7866 start: this.pos(row + from, column),
7867 end: this.pos(row + to, column = 0),
7868 action: delta.action,
7869 lines: chunk
7870 }, true);
7871 } while(true);
7872 };
7873 this.revertDelta = function(delta) {
7874 this.applyDelta({
7875 start: this.clonePos(delta.start),
7876 end: this.clonePos(delta.end),
7877 action: (delta.action == "insert" ? "remove" : "insert"),
7878 lines: delta.lines.slice()
7879 });
7880 };
7881 this.indexToPosition = function(index, startRow) {
7882 var lines = this.$lines || this.getAllLines();
7883 var newlineLength = this.getNewLineCharacter().length;
7884 for (var i = startRow || 0, l = lines.length; i < l; i++) {
7885 index -= lines[i].length + newlineLength;
7886 if (index < 0)
7887 return {row: i, column: index + lines[i].length + newlineLength};
7888 }
7889 return {row: l-1, column: lines[l-1].length};
7890 };
7891 this.positionToIndex = function(pos, startRow) {
7892 var lines = this.$lines || this.getAllLines();
7893 var newlineLength = this.getNewLineCharacter().length;
7894 var index = 0;
7895 var row = Math.min(pos.row, lines.length);
7896 for (var i = startRow || 0; i < row; ++i)
7897 index += lines[i].length + newlineLength;
7898
7899 return index + pos.column;
7900 };
7901
7902}).call(Document.prototype);
7903
7904exports.Document = Document;
7905});
7906
7907ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(acequire, exports, module) {
7908
7909var oop = acequire("./lib/oop");
7910var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
7911
7912var BackgroundTokenizer = function(tokenizer, editor) {
7913 this.running = false;
7914 this.lines = [];
7915 this.states = [];
7916 this.currentLine = 0;
7917 this.tokenizer = tokenizer;
7918
7919 var self = this;
7920
7921 this.$worker = function() {
7922 if (!self.running) { return; }
7923
7924 var workerStart = new Date();
7925 var currentLine = self.currentLine;
7926 var endLine = -1;
7927 var doc = self.doc;
7928
7929 var startLine = currentLine;
7930 while (self.lines[currentLine])
7931 currentLine++;
7932
7933 var len = doc.getLength();
7934 var processedLines = 0;
7935 self.running = false;
7936 while (currentLine < len) {
7937 self.$tokenizeRow(currentLine);
7938 endLine = currentLine;
7939 do {
7940 currentLine++;
7941 } while (self.lines[currentLine]);
7942 processedLines ++;
7943 if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) {
7944 self.running = setTimeout(self.$worker, 20);
7945 break;
7946 }
7947 }
7948 self.currentLine = currentLine;
7949
7950 if (endLine == -1)
7951 endLine = currentLine;
7952
7953 if (startLine <= endLine)
7954 self.fireUpdateEvent(startLine, endLine);
7955 };
7956};
7957
7958(function(){
7959
7960 oop.implement(this, EventEmitter);
7961 this.setTokenizer = function(tokenizer) {
7962 this.tokenizer = tokenizer;
7963 this.lines = [];
7964 this.states = [];
7965
7966 this.start(0);
7967 };
7968 this.setDocument = function(doc) {
7969 this.doc = doc;
7970 this.lines = [];
7971 this.states = [];
7972
7973 this.stop();
7974 };
7975 this.fireUpdateEvent = function(firstRow, lastRow) {
7976 var data = {
7977 first: firstRow,
7978 last: lastRow
7979 };
7980 this._signal("update", {data: data});
7981 };
7982 this.start = function(startRow) {
7983 this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
7984 this.lines.splice(this.currentLine, this.lines.length);
7985 this.states.splice(this.currentLine, this.states.length);
7986
7987 this.stop();
7988 this.running = setTimeout(this.$worker, 700);
7989 };
7990
7991 this.scheduleStart = function() {
7992 if (!this.running)
7993 this.running = setTimeout(this.$worker, 700);
7994 };
7995
7996 this.$updateOnChange = function(delta) {
7997 var startRow = delta.start.row;
7998 var len = delta.end.row - startRow;
7999
8000 if (len === 0) {
8001 this.lines[startRow] = null;
8002 } else if (delta.action == "remove") {
8003 this.lines.splice(startRow, len + 1, null);
8004 this.states.splice(startRow, len + 1, null);
8005 } else {
8006 var args = Array(len + 1);
8007 args.unshift(startRow, 1);
8008 this.lines.splice.apply(this.lines, args);
8009 this.states.splice.apply(this.states, args);
8010 }
8011
8012 this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
8013
8014 this.stop();
8015 };
8016 this.stop = function() {
8017 if (this.running)
8018 clearTimeout(this.running);
8019 this.running = false;
8020 };
8021 this.getTokens = function(row) {
8022 return this.lines[row] || this.$tokenizeRow(row);
8023 };
8024 this.getState = function(row) {
8025 if (this.currentLine == row)
8026 this.$tokenizeRow(row);
8027 return this.states[row] || "start";
8028 };
8029
8030 this.$tokenizeRow = function(row) {
8031 var line = this.doc.getLine(row);
8032 var state = this.states[row - 1];
8033
8034 var data = this.tokenizer.getLineTokens(line, state, row);
8035
8036 if (this.states[row] + "" !== data.state + "") {
8037 this.states[row] = data.state;
8038 this.lines[row + 1] = null;
8039 if (this.currentLine > row + 1)
8040 this.currentLine = row + 1;
8041 } else if (this.currentLine == row) {
8042 this.currentLine = row + 1;
8043 }
8044
8045 return this.lines[row] = data.tokens;
8046 };
8047
8048}).call(BackgroundTokenizer.prototype);
8049
8050exports.BackgroundTokenizer = BackgroundTokenizer;
8051});
8052
8053ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(acequire, exports, module) {
8054
8055var lang = acequire("./lib/lang");
8056acequire("./lib/oop");
8057var Range = acequire("./range").Range;
8058
8059var SearchHighlight = function(regExp, clazz, type) {
8060 this.setRegexp(regExp);
8061 this.clazz = clazz;
8062 this.type = type || "text";
8063};
8064
8065(function() {
8066 this.MAX_RANGES = 500;
8067
8068 this.setRegexp = function(regExp) {
8069 if (this.regExp+"" == regExp+"")
8070 return;
8071 this.regExp = regExp;
8072 this.cache = [];
8073 };
8074
8075 this.update = function(html, markerLayer, session, config) {
8076 if (!this.regExp)
8077 return;
8078 var start = config.firstRow, end = config.lastRow;
8079
8080 for (var i = start; i <= end; i++) {
8081 var ranges = this.cache[i];
8082 if (ranges == null) {
8083 ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);
8084 if (ranges.length > this.MAX_RANGES)
8085 ranges = ranges.slice(0, this.MAX_RANGES);
8086 ranges = ranges.map(function(match) {
8087 return new Range(i, match.offset, i, match.offset + match.length);
8088 });
8089 this.cache[i] = ranges.length ? ranges : "";
8090 }
8091
8092 for (var j = ranges.length; j --; ) {
8093 markerLayer.drawSingleLineMarker(
8094 html, ranges[j].toScreenRange(session), this.clazz, config);
8095 }
8096 }
8097 };
8098
8099}).call(SearchHighlight.prototype);
8100
8101exports.SearchHighlight = SearchHighlight;
8102});
8103
8104ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"], function(acequire, exports, module) {
8105
8106var Range = acequire("../range").Range;
8107function FoldLine(foldData, folds) {
8108 this.foldData = foldData;
8109 if (Array.isArray(folds)) {
8110 this.folds = folds;
8111 } else {
8112 folds = this.folds = [ folds ];
8113 }
8114
8115 var last = folds[folds.length - 1];
8116 this.range = new Range(folds[0].start.row, folds[0].start.column,
8117 last.end.row, last.end.column);
8118 this.start = this.range.start;
8119 this.end = this.range.end;
8120
8121 this.folds.forEach(function(fold) {
8122 fold.setFoldLine(this);
8123 }, this);
8124}
8125
8126(function() {
8127 this.shiftRow = function(shift) {
8128 this.start.row += shift;
8129 this.end.row += shift;
8130 this.folds.forEach(function(fold) {
8131 fold.start.row += shift;
8132 fold.end.row += shift;
8133 });
8134 };
8135
8136 this.addFold = function(fold) {
8137 if (fold.sameRow) {
8138 if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
8139 throw new Error("Can't add a fold to this FoldLine as it has no connection");
8140 }
8141 this.folds.push(fold);
8142 this.folds.sort(function(a, b) {
8143 return -a.range.compareEnd(b.start.row, b.start.column);
8144 });
8145 if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
8146 this.end.row = fold.end.row;
8147 this.end.column = fold.end.column;
8148 } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
8149 this.start.row = fold.start.row;
8150 this.start.column = fold.start.column;
8151 }
8152 } else if (fold.start.row == this.end.row) {
8153 this.folds.push(fold);
8154 this.end.row = fold.end.row;
8155 this.end.column = fold.end.column;
8156 } else if (fold.end.row == this.start.row) {
8157 this.folds.unshift(fold);
8158 this.start.row = fold.start.row;
8159 this.start.column = fold.start.column;
8160 } else {
8161 throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
8162 }
8163 fold.foldLine = this;
8164 };
8165
8166 this.containsRow = function(row) {
8167 return row >= this.start.row && row <= this.end.row;
8168 };
8169
8170 this.walk = function(callback, endRow, endColumn) {
8171 var lastEnd = 0,
8172 folds = this.folds,
8173 fold,
8174 cmp, stop, isNewRow = true;
8175
8176 if (endRow == null) {
8177 endRow = this.end.row;
8178 endColumn = this.end.column;
8179 }
8180
8181 for (var i = 0; i < folds.length; i++) {
8182 fold = folds[i];
8183
8184 cmp = fold.range.compareStart(endRow, endColumn);
8185 if (cmp == -1) {
8186 callback(null, endRow, endColumn, lastEnd, isNewRow);
8187 return;
8188 }
8189
8190 stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
8191 stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
8192 if (stop || cmp === 0) {
8193 return;
8194 }
8195 isNewRow = !fold.sameRow;
8196 lastEnd = fold.end.column;
8197 }
8198 callback(null, endRow, endColumn, lastEnd, isNewRow);
8199 };
8200
8201 this.getNextFoldTo = function(row, column) {
8202 var fold, cmp;
8203 for (var i = 0; i < this.folds.length; i++) {
8204 fold = this.folds[i];
8205 cmp = fold.range.compareEnd(row, column);
8206 if (cmp == -1) {
8207 return {
8208 fold: fold,
8209 kind: "after"
8210 };
8211 } else if (cmp === 0) {
8212 return {
8213 fold: fold,
8214 kind: "inside"
8215 };
8216 }
8217 }
8218 return null;
8219 };
8220
8221 this.addRemoveChars = function(row, column, len) {
8222 var ret = this.getNextFoldTo(row, column),
8223 fold, folds;
8224 if (ret) {
8225 fold = ret.fold;
8226 if (ret.kind == "inside"
8227 && fold.start.column != column
8228 && fold.start.row != row)
8229 {
8230 window.console && window.console.log(row, column, fold);
8231 } else if (fold.start.row == row) {
8232 folds = this.folds;
8233 var i = folds.indexOf(fold);
8234 if (i === 0) {
8235 this.start.column += len;
8236 }
8237 for (i; i < folds.length; i++) {
8238 fold = folds[i];
8239 fold.start.column += len;
8240 if (!fold.sameRow) {
8241 return;
8242 }
8243 fold.end.column += len;
8244 }
8245 this.end.column += len;
8246 }
8247 }
8248 };
8249
8250 this.split = function(row, column) {
8251 var pos = this.getNextFoldTo(row, column);
8252
8253 if (!pos || pos.kind == "inside")
8254 return null;
8255
8256 var fold = pos.fold;
8257 var folds = this.folds;
8258 var foldData = this.foldData;
8259
8260 var i = folds.indexOf(fold);
8261 var foldBefore = folds[i - 1];
8262 this.end.row = foldBefore.end.row;
8263 this.end.column = foldBefore.end.column;
8264 folds = folds.splice(i, folds.length - i);
8265
8266 var newFoldLine = new FoldLine(foldData, folds);
8267 foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
8268 return newFoldLine;
8269 };
8270
8271 this.merge = function(foldLineNext) {
8272 var folds = foldLineNext.folds;
8273 for (var i = 0; i < folds.length; i++) {
8274 this.addFold(folds[i]);
8275 }
8276 var foldData = this.foldData;
8277 foldData.splice(foldData.indexOf(foldLineNext), 1);
8278 };
8279
8280 this.toString = function() {
8281 var ret = [this.range.toString() + ": [" ];
8282
8283 this.folds.forEach(function(fold) {
8284 ret.push(" " + fold.toString());
8285 });
8286 ret.push("]");
8287 return ret.join("\n");
8288 };
8289
8290 this.idxToPosition = function(idx) {
8291 var lastFoldEndColumn = 0;
8292
8293 for (var i = 0; i < this.folds.length; i++) {
8294 var fold = this.folds[i];
8295
8296 idx -= fold.start.column - lastFoldEndColumn;
8297 if (idx < 0) {
8298 return {
8299 row: fold.start.row,
8300 column: fold.start.column + idx
8301 };
8302 }
8303
8304 idx -= fold.placeholder.length;
8305 if (idx < 0) {
8306 return fold.start;
8307 }
8308
8309 lastFoldEndColumn = fold.end.column;
8310 }
8311
8312 return {
8313 row: this.end.row,
8314 column: this.end.column + idx
8315 };
8316 };
8317}).call(FoldLine.prototype);
8318
8319exports.FoldLine = FoldLine;
8320});
8321
8322ace.define("ace/range_list",["require","exports","module","ace/range"], function(acequire, exports, module) {
8323var Range = acequire("./range").Range;
8324var comparePoints = Range.comparePoints;
8325
8326var RangeList = function() {
8327 this.ranges = [];
8328};
8329
8330(function() {
8331 this.comparePoints = comparePoints;
8332
8333 this.pointIndex = function(pos, excludeEdges, startIndex) {
8334 var list = this.ranges;
8335
8336 for (var i = startIndex || 0; i < list.length; i++) {
8337 var range = list[i];
8338 var cmpEnd = comparePoints(pos, range.end);
8339 if (cmpEnd > 0)
8340 continue;
8341 var cmpStart = comparePoints(pos, range.start);
8342 if (cmpEnd === 0)
8343 return excludeEdges && cmpStart !== 0 ? -i-2 : i;
8344 if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
8345 return i;
8346
8347 return -i-1;
8348 }
8349 return -i - 1;
8350 };
8351
8352 this.add = function(range) {
8353 var excludeEdges = !range.isEmpty();
8354 var startIndex = this.pointIndex(range.start, excludeEdges);
8355 if (startIndex < 0)
8356 startIndex = -startIndex - 1;
8357
8358 var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
8359
8360 if (endIndex < 0)
8361 endIndex = -endIndex - 1;
8362 else
8363 endIndex++;
8364 return this.ranges.splice(startIndex, endIndex - startIndex, range);
8365 };
8366
8367 this.addList = function(list) {
8368 var removed = [];
8369 for (var i = list.length; i--; ) {
8370 removed.push.apply(removed, this.add(list[i]));
8371 }
8372 return removed;
8373 };
8374
8375 this.substractPoint = function(pos) {
8376 var i = this.pointIndex(pos);
8377
8378 if (i >= 0)
8379 return this.ranges.splice(i, 1);
8380 };
8381 this.merge = function() {
8382 var removed = [];
8383 var list = this.ranges;
8384
8385 list = list.sort(function(a, b) {
8386 return comparePoints(a.start, b.start);
8387 });
8388
8389 var next = list[0], range;
8390 for (var i = 1; i < list.length; i++) {
8391 range = next;
8392 next = list[i];
8393 var cmp = comparePoints(range.end, next.start);
8394 if (cmp < 0)
8395 continue;
8396
8397 if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
8398 continue;
8399
8400 if (comparePoints(range.end, next.end) < 0) {
8401 range.end.row = next.end.row;
8402 range.end.column = next.end.column;
8403 }
8404
8405 list.splice(i, 1);
8406 removed.push(next);
8407 next = range;
8408 i--;
8409 }
8410
8411 this.ranges = list;
8412
8413 return removed;
8414 };
8415
8416 this.contains = function(row, column) {
8417 return this.pointIndex({row: row, column: column}) >= 0;
8418 };
8419
8420 this.containsPoint = function(pos) {
8421 return this.pointIndex(pos) >= 0;
8422 };
8423
8424 this.rangeAtPoint = function(pos) {
8425 var i = this.pointIndex(pos);
8426 if (i >= 0)
8427 return this.ranges[i];
8428 };
8429
8430
8431 this.clipRows = function(startRow, endRow) {
8432 var list = this.ranges;
8433 if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)
8434 return [];
8435
8436 var startIndex = this.pointIndex({row: startRow, column: 0});
8437 if (startIndex < 0)
8438 startIndex = -startIndex - 1;
8439 var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);
8440 if (endIndex < 0)
8441 endIndex = -endIndex - 1;
8442
8443 var clipped = [];
8444 for (var i = startIndex; i < endIndex; i++) {
8445 clipped.push(list[i]);
8446 }
8447 return clipped;
8448 };
8449
8450 this.removeAll = function() {
8451 return this.ranges.splice(0, this.ranges.length);
8452 };
8453
8454 this.attach = function(session) {
8455 if (this.session)
8456 this.detach();
8457
8458 this.session = session;
8459 this.onChange = this.$onChange.bind(this);
8460
8461 this.session.on('change', this.onChange);
8462 };
8463
8464 this.detach = function() {
8465 if (!this.session)
8466 return;
8467 this.session.removeListener('change', this.onChange);
8468 this.session = null;
8469 };
8470
8471 this.$onChange = function(delta) {
8472 if (delta.action == "insert"){
8473 var start = delta.start;
8474 var end = delta.end;
8475 } else {
8476 var end = delta.start;
8477 var start = delta.end;
8478 }
8479 var startRow = start.row;
8480 var endRow = end.row;
8481 var lineDif = endRow - startRow;
8482
8483 var colDiff = -start.column + end.column;
8484 var ranges = this.ranges;
8485
8486 for (var i = 0, n = ranges.length; i < n; i++) {
8487 var r = ranges[i];
8488 if (r.end.row < startRow)
8489 continue;
8490 if (r.start.row > startRow)
8491 break;
8492
8493 if (r.start.row == startRow && r.start.column >= start.column ) {
8494 if (r.start.column == start.column && this.$insertRight) ; else {
8495 r.start.column += colDiff;
8496 r.start.row += lineDif;
8497 }
8498 }
8499 if (r.end.row == startRow && r.end.column >= start.column) {
8500 if (r.end.column == start.column && this.$insertRight) {
8501 continue;
8502 }
8503 if (r.end.column == start.column && colDiff > 0 && i < n - 1) {
8504 if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
8505 r.end.column -= colDiff;
8506 }
8507 r.end.column += colDiff;
8508 r.end.row += lineDif;
8509 }
8510 }
8511
8512 if (lineDif != 0 && i < n) {
8513 for (; i < n; i++) {
8514 var r = ranges[i];
8515 r.start.row += lineDif;
8516 r.end.row += lineDif;
8517 }
8518 }
8519 };
8520
8521}).call(RangeList.prototype);
8522
8523exports.RangeList = RangeList;
8524});
8525
8526ace.define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"], function(acequire, exports, module) {
8527
8528acequire("../range").Range;
8529var RangeList = acequire("../range_list").RangeList;
8530var oop = acequire("../lib/oop");
8531var Fold = exports.Fold = function(range, placeholder) {
8532 this.foldLine = null;
8533 this.placeholder = placeholder;
8534 this.range = range;
8535 this.start = range.start;
8536 this.end = range.end;
8537
8538 this.sameRow = range.start.row == range.end.row;
8539 this.subFolds = this.ranges = [];
8540};
8541
8542oop.inherits(Fold, RangeList);
8543
8544(function() {
8545
8546 this.toString = function() {
8547 return '"' + this.placeholder + '" ' + this.range.toString();
8548 };
8549
8550 this.setFoldLine = function(foldLine) {
8551 this.foldLine = foldLine;
8552 this.subFolds.forEach(function(fold) {
8553 fold.setFoldLine(foldLine);
8554 });
8555 };
8556
8557 this.clone = function() {
8558 var range = this.range.clone();
8559 var fold = new Fold(range, this.placeholder);
8560 this.subFolds.forEach(function(subFold) {
8561 fold.subFolds.push(subFold.clone());
8562 });
8563 fold.collapseChildren = this.collapseChildren;
8564 return fold;
8565 };
8566
8567 this.addSubFold = function(fold) {
8568 if (this.range.isEqual(fold))
8569 return;
8570
8571 if (!this.range.containsRange(fold))
8572 throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
8573 consumeRange(fold, this.start);
8574
8575 var row = fold.start.row, column = fold.start.column;
8576 for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
8577 cmp = this.subFolds[i].range.compare(row, column);
8578 if (cmp != 1)
8579 break;
8580 }
8581 var afterStart = this.subFolds[i];
8582
8583 if (cmp == 0)
8584 return afterStart.addSubFold(fold);
8585 var row = fold.range.end.row, column = fold.range.end.column;
8586 for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
8587 cmp = this.subFolds[j].range.compare(row, column);
8588 if (cmp != 1)
8589 break;
8590 }
8591 this.subFolds[j];
8592
8593 if (cmp == 0)
8594 throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
8595
8596 this.subFolds.splice(i, j - i, fold);
8597 fold.setFoldLine(this.foldLine);
8598
8599 return fold;
8600 };
8601
8602 this.restoreRange = function(range) {
8603 return restoreRange(range, this.start);
8604 };
8605
8606}).call(Fold.prototype);
8607
8608function consumePoint(point, anchor) {
8609 point.row -= anchor.row;
8610 if (point.row == 0)
8611 point.column -= anchor.column;
8612}
8613function consumeRange(range, anchor) {
8614 consumePoint(range.start, anchor);
8615 consumePoint(range.end, anchor);
8616}
8617function restorePoint(point, anchor) {
8618 if (point.row == 0)
8619 point.column += anchor.column;
8620 point.row += anchor.row;
8621}
8622function restoreRange(range, anchor) {
8623 restorePoint(range.start, anchor);
8624 restorePoint(range.end, anchor);
8625}
8626
8627});
8628
8629ace.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) {
8630
8631var Range = acequire("../range").Range;
8632var FoldLine = acequire("./fold_line").FoldLine;
8633var Fold = acequire("./fold").Fold;
8634var TokenIterator = acequire("../token_iterator").TokenIterator;
8635
8636function Folding() {
8637 this.getFoldAt = function(row, column, side) {
8638 var foldLine = this.getFoldLine(row);
8639 if (!foldLine)
8640 return null;
8641
8642 var folds = foldLine.folds;
8643 for (var i = 0; i < folds.length; i++) {
8644 var fold = folds[i];
8645 if (fold.range.contains(row, column)) {
8646 if (side == 1 && fold.range.isEnd(row, column)) {
8647 continue;
8648 } else if (side == -1 && fold.range.isStart(row, column)) {
8649 continue;
8650 }
8651 return fold;
8652 }
8653 }
8654 };
8655 this.getFoldsInRange = function(range) {
8656 var start = range.start;
8657 var end = range.end;
8658 var foldLines = this.$foldData;
8659 var foundFolds = [];
8660
8661 start.column += 1;
8662 end.column -= 1;
8663
8664 for (var i = 0; i < foldLines.length; i++) {
8665 var cmp = foldLines[i].range.compareRange(range);
8666 if (cmp == 2) {
8667 continue;
8668 }
8669 else if (cmp == -2) {
8670 break;
8671 }
8672
8673 var folds = foldLines[i].folds;
8674 for (var j = 0; j < folds.length; j++) {
8675 var fold = folds[j];
8676 cmp = fold.range.compareRange(range);
8677 if (cmp == -2) {
8678 break;
8679 } else if (cmp == 2) {
8680 continue;
8681 } else
8682 if (cmp == 42) {
8683 break;
8684 }
8685 foundFolds.push(fold);
8686 }
8687 }
8688 start.column -= 1;
8689 end.column += 1;
8690
8691 return foundFolds;
8692 };
8693
8694 this.getFoldsInRangeList = function(ranges) {
8695 if (Array.isArray(ranges)) {
8696 var folds = [];
8697 ranges.forEach(function(range) {
8698 folds = folds.concat(this.getFoldsInRange(range));
8699 }, this);
8700 } else {
8701 var folds = this.getFoldsInRange(ranges);
8702 }
8703 return folds;
8704 };
8705 this.getAllFolds = function() {
8706 var folds = [];
8707 var foldLines = this.$foldData;
8708
8709 for (var i = 0; i < foldLines.length; i++)
8710 for (var j = 0; j < foldLines[i].folds.length; j++)
8711 folds.push(foldLines[i].folds[j]);
8712
8713 return folds;
8714 };
8715 this.getFoldStringAt = function(row, column, trim, foldLine) {
8716 foldLine = foldLine || this.getFoldLine(row);
8717 if (!foldLine)
8718 return null;
8719
8720 var lastFold = {
8721 end: { column: 0 }
8722 };
8723 var str, fold;
8724 for (var i = 0; i < foldLine.folds.length; i++) {
8725 fold = foldLine.folds[i];
8726 var cmp = fold.range.compareEnd(row, column);
8727 if (cmp == -1) {
8728 str = this
8729 .getLine(fold.start.row)
8730 .substring(lastFold.end.column, fold.start.column);
8731 break;
8732 }
8733 else if (cmp === 0) {
8734 return null;
8735 }
8736 lastFold = fold;
8737 }
8738 if (!str)
8739 str = this.getLine(fold.start.row).substring(lastFold.end.column);
8740
8741 if (trim == -1)
8742 return str.substring(0, column - lastFold.end.column);
8743 else if (trim == 1)
8744 return str.substring(column - lastFold.end.column);
8745 else
8746 return str;
8747 };
8748
8749 this.getFoldLine = function(docRow, startFoldLine) {
8750 var foldData = this.$foldData;
8751 var i = 0;
8752 if (startFoldLine)
8753 i = foldData.indexOf(startFoldLine);
8754 if (i == -1)
8755 i = 0;
8756 for (i; i < foldData.length; i++) {
8757 var foldLine = foldData[i];
8758 if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
8759 return foldLine;
8760 } else if (foldLine.end.row > docRow) {
8761 return null;
8762 }
8763 }
8764 return null;
8765 };
8766 this.getNextFoldLine = function(docRow, startFoldLine) {
8767 var foldData = this.$foldData;
8768 var i = 0;
8769 if (startFoldLine)
8770 i = foldData.indexOf(startFoldLine);
8771 if (i == -1)
8772 i = 0;
8773 for (i; i < foldData.length; i++) {
8774 var foldLine = foldData[i];
8775 if (foldLine.end.row >= docRow) {
8776 return foldLine;
8777 }
8778 }
8779 return null;
8780 };
8781
8782 this.getFoldedRowCount = function(first, last) {
8783 var foldData = this.$foldData, rowCount = last-first+1;
8784 for (var i = 0; i < foldData.length; i++) {
8785 var foldLine = foldData[i],
8786 end = foldLine.end.row,
8787 start = foldLine.start.row;
8788 if (end >= last) {
8789 if (start < last) {
8790 if (start >= first)
8791 rowCount -= last-start;
8792 else
8793 rowCount = 0; // in one fold
8794 }
8795 break;
8796 } else if (end >= first){
8797 if (start >= first) // fold inside range
8798 rowCount -= end-start;
8799 else
8800 rowCount -= end-first+1;
8801 }
8802 }
8803 return rowCount;
8804 };
8805
8806 this.$addFoldLine = function(foldLine) {
8807 this.$foldData.push(foldLine);
8808 this.$foldData.sort(function(a, b) {
8809 return a.start.row - b.start.row;
8810 });
8811 return foldLine;
8812 };
8813 this.addFold = function(placeholder, range) {
8814 var foldData = this.$foldData;
8815 var added = false;
8816 var fold;
8817
8818 if (placeholder instanceof Fold)
8819 fold = placeholder;
8820 else {
8821 fold = new Fold(range, placeholder);
8822 fold.collapseChildren = range.collapseChildren;
8823 }
8824 this.$clipRangeToDocument(fold.range);
8825
8826 var startRow = fold.start.row;
8827 var startColumn = fold.start.column;
8828 var endRow = fold.end.row;
8829 var endColumn = fold.end.column;
8830 if (!(startRow < endRow ||
8831 startRow == endRow && startColumn <= endColumn - 2))
8832 throw new Error("The range has to be at least 2 characters width");
8833
8834 var startFold = this.getFoldAt(startRow, startColumn, 1);
8835 var endFold = this.getFoldAt(endRow, endColumn, -1);
8836 if (startFold && endFold == startFold)
8837 return startFold.addSubFold(fold);
8838
8839 if (startFold && !startFold.range.isStart(startRow, startColumn))
8840 this.removeFold(startFold);
8841
8842 if (endFold && !endFold.range.isEnd(endRow, endColumn))
8843 this.removeFold(endFold);
8844 var folds = this.getFoldsInRange(fold.range);
8845 if (folds.length > 0) {
8846 this.removeFolds(folds);
8847 folds.forEach(function(subFold) {
8848 fold.addSubFold(subFold);
8849 });
8850 }
8851
8852 for (var i = 0; i < foldData.length; i++) {
8853 var foldLine = foldData[i];
8854 if (endRow == foldLine.start.row) {
8855 foldLine.addFold(fold);
8856 added = true;
8857 break;
8858 } else if (startRow == foldLine.end.row) {
8859 foldLine.addFold(fold);
8860 added = true;
8861 if (!fold.sameRow) {
8862 var foldLineNext = foldData[i + 1];
8863 if (foldLineNext && foldLineNext.start.row == endRow) {
8864 foldLine.merge(foldLineNext);
8865 break;
8866 }
8867 }
8868 break;
8869 } else if (endRow <= foldLine.start.row) {
8870 break;
8871 }
8872 }
8873
8874 if (!added)
8875 foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
8876
8877 if (this.$useWrapMode)
8878 this.$updateWrapData(foldLine.start.row, foldLine.start.row);
8879 else
8880 this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);
8881 this.$modified = true;
8882 this._signal("changeFold", { data: fold, action: "add" });
8883
8884 return fold;
8885 };
8886
8887 this.addFolds = function(folds) {
8888 folds.forEach(function(fold) {
8889 this.addFold(fold);
8890 }, this);
8891 };
8892
8893 this.removeFold = function(fold) {
8894 var foldLine = fold.foldLine;
8895 var startRow = foldLine.start.row;
8896 var endRow = foldLine.end.row;
8897
8898 var foldLines = this.$foldData;
8899 var folds = foldLine.folds;
8900 if (folds.length == 1) {
8901 foldLines.splice(foldLines.indexOf(foldLine), 1);
8902 } else
8903 if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
8904 folds.pop();
8905 foldLine.end.row = folds[folds.length - 1].end.row;
8906 foldLine.end.column = folds[folds.length - 1].end.column;
8907 } else
8908 if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
8909 folds.shift();
8910 foldLine.start.row = folds[0].start.row;
8911 foldLine.start.column = folds[0].start.column;
8912 } else
8913 if (fold.sameRow) {
8914 folds.splice(folds.indexOf(fold), 1);
8915 } else
8916 {
8917 var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
8918 folds = newFoldLine.folds;
8919 folds.shift();
8920 newFoldLine.start.row = folds[0].start.row;
8921 newFoldLine.start.column = folds[0].start.column;
8922 }
8923
8924 if (!this.$updating) {
8925 if (this.$useWrapMode)
8926 this.$updateWrapData(startRow, endRow);
8927 else
8928 this.$updateRowLengthCache(startRow, endRow);
8929 }
8930 this.$modified = true;
8931 this._signal("changeFold", { data: fold, action: "remove" });
8932 };
8933
8934 this.removeFolds = function(folds) {
8935 var cloneFolds = [];
8936 for (var i = 0; i < folds.length; i++) {
8937 cloneFolds.push(folds[i]);
8938 }
8939
8940 cloneFolds.forEach(function(fold) {
8941 this.removeFold(fold);
8942 }, this);
8943 this.$modified = true;
8944 };
8945
8946 this.expandFold = function(fold) {
8947 this.removeFold(fold);
8948 fold.subFolds.forEach(function(subFold) {
8949 fold.restoreRange(subFold);
8950 this.addFold(subFold);
8951 }, this);
8952 if (fold.collapseChildren > 0) {
8953 this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
8954 }
8955 fold.subFolds = [];
8956 };
8957
8958 this.expandFolds = function(folds) {
8959 folds.forEach(function(fold) {
8960 this.expandFold(fold);
8961 }, this);
8962 };
8963
8964 this.unfold = function(location, expandInner) {
8965 var range, folds;
8966 if (location == null) {
8967 range = new Range(0, 0, this.getLength(), 0);
8968 expandInner = true;
8969 } else if (typeof location == "number")
8970 range = new Range(location, 0, location, this.getLine(location).length);
8971 else if ("row" in location)
8972 range = Range.fromPoints(location, location);
8973 else
8974 range = location;
8975
8976 folds = this.getFoldsInRangeList(range);
8977 if (expandInner) {
8978 this.removeFolds(folds);
8979 } else {
8980 var subFolds = folds;
8981 while (subFolds.length) {
8982 this.expandFolds(subFolds);
8983 subFolds = this.getFoldsInRangeList(range);
8984 }
8985 }
8986 if (folds.length)
8987 return folds;
8988 };
8989 this.isRowFolded = function(docRow, startFoldRow) {
8990 return !!this.getFoldLine(docRow, startFoldRow);
8991 };
8992
8993 this.getRowFoldEnd = function(docRow, startFoldRow) {
8994 var foldLine = this.getFoldLine(docRow, startFoldRow);
8995 return foldLine ? foldLine.end.row : docRow;
8996 };
8997
8998 this.getRowFoldStart = function(docRow, startFoldRow) {
8999 var foldLine = this.getFoldLine(docRow, startFoldRow);
9000 return foldLine ? foldLine.start.row : docRow;
9001 };
9002
9003 this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
9004 if (startRow == null)
9005 startRow = foldLine.start.row;
9006 if (startColumn == null)
9007 startColumn = 0;
9008 if (endRow == null)
9009 endRow = foldLine.end.row;
9010 if (endColumn == null)
9011 endColumn = this.getLine(endRow).length;
9012 var doc = this.doc;
9013 var textLine = "";
9014
9015 foldLine.walk(function(placeholder, row, column, lastColumn) {
9016 if (row < startRow)
9017 return;
9018 if (row == startRow) {
9019 if (column < startColumn)
9020 return;
9021 lastColumn = Math.max(startColumn, lastColumn);
9022 }
9023
9024 if (placeholder != null) {
9025 textLine += placeholder;
9026 } else {
9027 textLine += doc.getLine(row).substring(lastColumn, column);
9028 }
9029 }, endRow, endColumn);
9030 return textLine;
9031 };
9032
9033 this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
9034 var foldLine = this.getFoldLine(row);
9035
9036 if (!foldLine) {
9037 var line;
9038 line = this.doc.getLine(row);
9039 return line.substring(startColumn || 0, endColumn || line.length);
9040 } else {
9041 return this.getFoldDisplayLine(
9042 foldLine, row, endColumn, startRow, startColumn);
9043 }
9044 };
9045
9046 this.$cloneFoldData = function() {
9047 var fd = [];
9048 fd = this.$foldData.map(function(foldLine) {
9049 var folds = foldLine.folds.map(function(fold) {
9050 return fold.clone();
9051 });
9052 return new FoldLine(fd, folds);
9053 });
9054
9055 return fd;
9056 };
9057
9058 this.toggleFold = function(tryToUnfold) {
9059 var selection = this.selection;
9060 var range = selection.getRange();
9061 var fold;
9062 var bracketPos;
9063
9064 if (range.isEmpty()) {
9065 var cursor = range.start;
9066 fold = this.getFoldAt(cursor.row, cursor.column);
9067
9068 if (fold) {
9069 this.expandFold(fold);
9070 return;
9071 } else if (bracketPos = this.findMatchingBracket(cursor)) {
9072 if (range.comparePoint(bracketPos) == 1) {
9073 range.end = bracketPos;
9074 } else {
9075 range.start = bracketPos;
9076 range.start.column++;
9077 range.end.column--;
9078 }
9079 } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
9080 if (range.comparePoint(bracketPos) == 1)
9081 range.end = bracketPos;
9082 else
9083 range.start = bracketPos;
9084
9085 range.start.column++;
9086 } else {
9087 range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
9088 }
9089 } else {
9090 var folds = this.getFoldsInRange(range);
9091 if (tryToUnfold && folds.length) {
9092 this.expandFolds(folds);
9093 return;
9094 } else if (folds.length == 1 ) {
9095 fold = folds[0];
9096 }
9097 }
9098
9099 if (!fold)
9100 fold = this.getFoldAt(range.start.row, range.start.column);
9101
9102 if (fold && fold.range.toString() == range.toString()) {
9103 this.expandFold(fold);
9104 return;
9105 }
9106
9107 var placeholder = "...";
9108 if (!range.isMultiLine()) {
9109 placeholder = this.getTextRange(range);
9110 if (placeholder.length < 4)
9111 return;
9112 placeholder = placeholder.trim().substring(0, 2) + "..";
9113 }
9114
9115 this.addFold(placeholder, range);
9116 };
9117
9118 this.getCommentFoldRange = function(row, column, dir) {
9119 var iterator = new TokenIterator(this, row, column);
9120 var token = iterator.getCurrentToken();
9121 var type = token.type;
9122 if (token && /^comment|string/.test(type)) {
9123 type = type.match(/comment|string/)[0];
9124 if (type == "comment")
9125 type += "|doc-start";
9126 var re = new RegExp(type);
9127 var range = new Range();
9128 if (dir != 1) {
9129 do {
9130 token = iterator.stepBackward();
9131 } while (token && re.test(token.type));
9132 iterator.stepForward();
9133 }
9134
9135 range.start.row = iterator.getCurrentTokenRow();
9136 range.start.column = iterator.getCurrentTokenColumn() + 2;
9137
9138 iterator = new TokenIterator(this, row, column);
9139
9140 if (dir != -1) {
9141 var lastRow = -1;
9142 do {
9143 token = iterator.stepForward();
9144 if (lastRow == -1) {
9145 var state = this.getState(iterator.$row);
9146 if (!re.test(state))
9147 lastRow = iterator.$row;
9148 } else if (iterator.$row > lastRow) {
9149 break;
9150 }
9151 } while (token && re.test(token.type));
9152 token = iterator.stepBackward();
9153 } else
9154 token = iterator.getCurrentToken();
9155
9156 range.end.row = iterator.getCurrentTokenRow();
9157 range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
9158 return range;
9159 }
9160 };
9161
9162 this.foldAll = function(startRow, endRow, depth) {
9163 if (depth == undefined)
9164 depth = 100000; // JSON.stringify doesn't hanle Infinity
9165 var foldWidgets = this.foldWidgets;
9166 if (!foldWidgets)
9167 return; // mode doesn't support folding
9168 endRow = endRow || this.getLength();
9169 startRow = startRow || 0;
9170 for (var row = startRow; row < endRow; row++) {
9171 if (foldWidgets[row] == null)
9172 foldWidgets[row] = this.getFoldWidget(row);
9173 if (foldWidgets[row] != "start")
9174 continue;
9175
9176 var range = this.getFoldWidgetRange(row);
9177 if (range && range.isMultiLine()
9178 && range.end.row <= endRow
9179 && range.start.row >= startRow
9180 ) {
9181 row = range.end.row;
9182 try {
9183 var fold = this.addFold("...", range);
9184 if (fold)
9185 fold.collapseChildren = depth;
9186 } catch(e) {}
9187 }
9188 }
9189 };
9190 this.$foldStyles = {
9191 "manual": 1,
9192 "markbegin": 1,
9193 "markbeginend": 1
9194 };
9195 this.$foldStyle = "markbegin";
9196 this.setFoldStyle = function(style) {
9197 if (!this.$foldStyles[style])
9198 throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]");
9199
9200 if (this.$foldStyle == style)
9201 return;
9202
9203 this.$foldStyle = style;
9204
9205 if (style == "manual")
9206 this.unfold();
9207 var mode = this.$foldMode;
9208 this.$setFolding(null);
9209 this.$setFolding(mode);
9210 };
9211
9212 this.$setFolding = function(foldMode) {
9213 if (this.$foldMode == foldMode)
9214 return;
9215
9216 this.$foldMode = foldMode;
9217
9218 this.off('change', this.$updateFoldWidgets);
9219 this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);
9220 this._signal("changeAnnotation");
9221
9222 if (!foldMode || this.$foldStyle == "manual") {
9223 this.foldWidgets = null;
9224 return;
9225 }
9226
9227 this.foldWidgets = [];
9228 this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);
9229 this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);
9230
9231 this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
9232 this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this);
9233 this.on('change', this.$updateFoldWidgets);
9234 this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);
9235 };
9236
9237 this.getParentFoldRangeData = function (row, ignoreCurrent) {
9238 var fw = this.foldWidgets;
9239 if (!fw || (ignoreCurrent && fw[row]))
9240 return {};
9241
9242 var i = row - 1, firstRange;
9243 while (i >= 0) {
9244 var c = fw[i];
9245 if (c == null)
9246 c = fw[i] = this.getFoldWidget(i);
9247
9248 if (c == "start") {
9249 var range = this.getFoldWidgetRange(i);
9250 if (!firstRange)
9251 firstRange = range;
9252 if (range && range.end.row >= row)
9253 break;
9254 }
9255 i--;
9256 }
9257
9258 return {
9259 range: i !== -1 && range,
9260 firstRange: firstRange
9261 };
9262 };
9263
9264 this.onFoldWidgetClick = function(row, e) {
9265 e = e.domEvent;
9266 var options = {
9267 children: e.shiftKey,
9268 all: e.ctrlKey || e.metaKey,
9269 siblings: e.altKey
9270 };
9271
9272 var range = this.$toggleFoldWidget(row, options);
9273 if (!range) {
9274 var el = (e.target || e.srcElement);
9275 if (el && /ace_fold-widget/.test(el.className))
9276 el.className += " ace_invalid";
9277 }
9278 };
9279
9280 this.$toggleFoldWidget = function(row, options) {
9281 if (!this.getFoldWidget)
9282 return;
9283 var type = this.getFoldWidget(row);
9284 var line = this.getLine(row);
9285
9286 var dir = type === "end" ? -1 : 1;
9287 var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
9288
9289 if (fold) {
9290 if (options.children || options.all)
9291 this.removeFold(fold);
9292 else
9293 this.expandFold(fold);
9294 return fold;
9295 }
9296
9297 var range = this.getFoldWidgetRange(row, true);
9298 if (range && !range.isMultiLine()) {
9299 fold = this.getFoldAt(range.start.row, range.start.column, 1);
9300 if (fold && range.isEqual(fold.range)) {
9301 this.removeFold(fold);
9302 return fold;
9303 }
9304 }
9305
9306 if (options.siblings) {
9307 var data = this.getParentFoldRangeData(row);
9308 if (data.range) {
9309 var startRow = data.range.start.row + 1;
9310 var endRow = data.range.end.row;
9311 }
9312 this.foldAll(startRow, endRow, options.all ? 10000 : 0);
9313 } else if (options.children) {
9314 endRow = range ? range.end.row : this.getLength();
9315 this.foldAll(row + 1, endRow, options.all ? 10000 : 0);
9316 } else if (range) {
9317 if (options.all)
9318 range.collapseChildren = 10000;
9319 this.addFold("...", range);
9320 }
9321
9322 return range;
9323 };
9324
9325
9326
9327 this.toggleFoldWidget = function(toggleParent) {
9328 var row = this.selection.getCursor().row;
9329 row = this.getRowFoldStart(row);
9330 var range = this.$toggleFoldWidget(row, {});
9331
9332 if (range)
9333 return;
9334 var data = this.getParentFoldRangeData(row, true);
9335 range = data.range || data.firstRange;
9336
9337 if (range) {
9338 row = range.start.row;
9339 var fold = this.getFoldAt(row, this.getLine(row).length, 1);
9340
9341 if (fold) {
9342 this.removeFold(fold);
9343 } else {
9344 this.addFold("...", range);
9345 }
9346 }
9347 };
9348
9349 this.updateFoldWidgets = function(delta) {
9350 var firstRow = delta.start.row;
9351 var len = delta.end.row - firstRow;
9352
9353 if (len === 0) {
9354 this.foldWidgets[firstRow] = null;
9355 } else if (delta.action == 'remove') {
9356 this.foldWidgets.splice(firstRow, len + 1, null);
9357 } else {
9358 var args = Array(len + 1);
9359 args.unshift(firstRow, 1);
9360 this.foldWidgets.splice.apply(this.foldWidgets, args);
9361 }
9362 };
9363 this.tokenizerUpdateFoldWidgets = function(e) {
9364 var rows = e.data;
9365 if (rows.first != rows.last) {
9366 if (this.foldWidgets.length > rows.first)
9367 this.foldWidgets.splice(rows.first, this.foldWidgets.length);
9368 }
9369 };
9370}
9371
9372exports.Folding = Folding;
9373
9374});
9375
9376ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"], function(acequire, exports, module) {
9377
9378var TokenIterator = acequire("../token_iterator").TokenIterator;
9379var Range = acequire("../range").Range;
9380
9381
9382function BracketMatch() {
9383
9384 this.findMatchingBracket = function(position, chr) {
9385 if (position.column == 0) return null;
9386
9387 var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);
9388 if (charBeforeCursor == "") return null;
9389
9390 var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
9391 if (!match)
9392 return null;
9393
9394 if (match[1])
9395 return this.$findClosingBracket(match[1], position);
9396 else
9397 return this.$findOpeningBracket(match[2], position);
9398 };
9399
9400 this.getBracketRange = function(pos) {
9401 var line = this.getLine(pos.row);
9402 var before = true, range;
9403
9404 var chr = line.charAt(pos.column-1);
9405 var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9406 if (!match) {
9407 chr = line.charAt(pos.column);
9408 pos = {row: pos.row, column: pos.column + 1};
9409 match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9410 before = false;
9411 }
9412 if (!match)
9413 return null;
9414
9415 if (match[1]) {
9416 var bracketPos = this.$findClosingBracket(match[1], pos);
9417 if (!bracketPos)
9418 return null;
9419 range = Range.fromPoints(pos, bracketPos);
9420 if (!before) {
9421 range.end.column++;
9422 range.start.column--;
9423 }
9424 range.cursor = range.end;
9425 } else {
9426 var bracketPos = this.$findOpeningBracket(match[2], pos);
9427 if (!bracketPos)
9428 return null;
9429 range = Range.fromPoints(bracketPos, pos);
9430 if (!before) {
9431 range.start.column++;
9432 range.end.column--;
9433 }
9434 range.cursor = range.start;
9435 }
9436
9437 return range;
9438 };
9439
9440 this.$brackets = {
9441 ")": "(",
9442 "(": ")",
9443 "]": "[",
9444 "[": "]",
9445 "{": "}",
9446 "}": "{"
9447 };
9448
9449 this.$findOpeningBracket = function(bracket, position, typeRe) {
9450 var openBracket = this.$brackets[bracket];
9451 var depth = 1;
9452
9453 var iterator = new TokenIterator(this, position.row, position.column);
9454 var token = iterator.getCurrentToken();
9455 if (!token)
9456 token = iterator.stepForward();
9457 if (!token)
9458 return;
9459
9460 if (!typeRe){
9461 typeRe = new RegExp(
9462 "(\\.?" +
9463 token.type.replace(".", "\\.").replace("rparen", ".paren")
9464 .replace(/\b(?:end)\b/, "(?:start|begin|end)")
9465 + ")+"
9466 );
9467 }
9468 var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
9469 var value = token.value;
9470
9471 while (true) {
9472
9473 while (valueIndex >= 0) {
9474 var chr = value.charAt(valueIndex);
9475 if (chr == openBracket) {
9476 depth -= 1;
9477 if (depth == 0) {
9478 return {row: iterator.getCurrentTokenRow(),
9479 column: valueIndex + iterator.getCurrentTokenColumn()};
9480 }
9481 }
9482 else if (chr == bracket) {
9483 depth += 1;
9484 }
9485 valueIndex -= 1;
9486 }
9487 do {
9488 token = iterator.stepBackward();
9489 } while (token && !typeRe.test(token.type));
9490
9491 if (token == null)
9492 break;
9493
9494 value = token.value;
9495 valueIndex = value.length - 1;
9496 }
9497
9498 return null;
9499 };
9500
9501 this.$findClosingBracket = function(bracket, position, typeRe) {
9502 var closingBracket = this.$brackets[bracket];
9503 var depth = 1;
9504
9505 var iterator = new TokenIterator(this, position.row, position.column);
9506 var token = iterator.getCurrentToken();
9507 if (!token)
9508 token = iterator.stepForward();
9509 if (!token)
9510 return;
9511
9512 if (!typeRe){
9513 typeRe = new RegExp(
9514 "(\\.?" +
9515 token.type.replace(".", "\\.").replace("lparen", ".paren")
9516 .replace(/\b(?:start|begin)\b/, "(?:start|begin|end)")
9517 + ")+"
9518 );
9519 }
9520 var valueIndex = position.column - iterator.getCurrentTokenColumn();
9521
9522 while (true) {
9523
9524 var value = token.value;
9525 var valueLength = value.length;
9526 while (valueIndex < valueLength) {
9527 var chr = value.charAt(valueIndex);
9528 if (chr == closingBracket) {
9529 depth -= 1;
9530 if (depth == 0) {
9531 return {row: iterator.getCurrentTokenRow(),
9532 column: valueIndex + iterator.getCurrentTokenColumn()};
9533 }
9534 }
9535 else if (chr == bracket) {
9536 depth += 1;
9537 }
9538 valueIndex += 1;
9539 }
9540 do {
9541 token = iterator.stepForward();
9542 } while (token && !typeRe.test(token.type));
9543
9544 if (token == null)
9545 break;
9546
9547 valueIndex = 0;
9548 }
9549
9550 return null;
9551 };
9552}
9553exports.BracketMatch = BracketMatch;
9554
9555});
9556
9557ace.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) {
9558
9559var oop = acequire("./lib/oop");
9560var lang = acequire("./lib/lang");
9561var BidiHandler = acequire("./bidihandler").BidiHandler;
9562var config = acequire("./config");
9563var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
9564var Selection = acequire("./selection").Selection;
9565var TextMode = acequire("./mode/text").Mode;
9566var Range = acequire("./range").Range;
9567var Document = acequire("./document").Document;
9568var BackgroundTokenizer = acequire("./background_tokenizer").BackgroundTokenizer;
9569var SearchHighlight = acequire("./search_highlight").SearchHighlight;
9570
9571var EditSession = function(text, mode) {
9572 this.$breakpoints = [];
9573 this.$decorations = [];
9574 this.$frontMarkers = {};
9575 this.$backMarkers = {};
9576 this.$markerId = 1;
9577 this.$undoSelect = true;
9578
9579 this.$foldData = [];
9580 this.id = "session" + (++EditSession.$uid);
9581 this.$foldData.toString = function() {
9582 return this.join("\n");
9583 };
9584 this.on("changeFold", this.onChangeFold.bind(this));
9585 this.$onChange = this.onChange.bind(this);
9586
9587 if (typeof text != "object" || !text.getLine)
9588 text = new Document(text);
9589
9590 this.$bidiHandler = new BidiHandler(this);
9591 this.setDocument(text);
9592 this.selection = new Selection(this);
9593
9594 config.resetOptions(this);
9595 this.setMode(mode);
9596 config._signal("session", this);
9597};
9598
9599
9600EditSession.$uid = 0;
9601
9602(function() {
9603
9604 oop.implement(this, EventEmitter);
9605 this.setDocument = function(doc) {
9606 if (this.doc)
9607 this.doc.removeListener("change", this.$onChange);
9608
9609 this.doc = doc;
9610 doc.on("change", this.$onChange);
9611
9612 if (this.bgTokenizer)
9613 this.bgTokenizer.setDocument(this.getDocument());
9614
9615 this.resetCaches();
9616 };
9617 this.getDocument = function() {
9618 return this.doc;
9619 };
9620 this.$resetRowCache = function(docRow) {
9621 if (!docRow) {
9622 this.$docRowCache = [];
9623 this.$screenRowCache = [];
9624 return;
9625 }
9626 var l = this.$docRowCache.length;
9627 var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;
9628 if (l > i) {
9629 this.$docRowCache.splice(i, l);
9630 this.$screenRowCache.splice(i, l);
9631 }
9632 };
9633
9634 this.$getRowCacheIndex = function(cacheArray, val) {
9635 var low = 0;
9636 var hi = cacheArray.length - 1;
9637
9638 while (low <= hi) {
9639 var mid = (low + hi) >> 1;
9640 var c = cacheArray[mid];
9641
9642 if (val > c)
9643 low = mid + 1;
9644 else if (val < c)
9645 hi = mid - 1;
9646 else
9647 return mid;
9648 }
9649
9650 return low -1;
9651 };
9652
9653 this.resetCaches = function() {
9654 this.$modified = true;
9655 this.$wrapData = [];
9656 this.$rowLengthCache = [];
9657 this.$resetRowCache(0);
9658 if (this.bgTokenizer)
9659 this.bgTokenizer.start(0);
9660 };
9661
9662 this.onChangeFold = function(e) {
9663 var fold = e.data;
9664 this.$resetRowCache(fold.start.row);
9665 };
9666
9667 this.onChange = function(delta) {
9668 this.$modified = true;
9669 this.$bidiHandler.onChange(delta);
9670 this.$resetRowCache(delta.start.row);
9671
9672 var removedFolds = this.$updateInternalDataOnChange(delta);
9673 if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
9674 this.$deltasDoc.push(delta);
9675 if (removedFolds && removedFolds.length != 0) {
9676 this.$deltasFold.push({
9677 action: "removeFolds",
9678 folds: removedFolds
9679 });
9680 }
9681
9682 this.$informUndoManager.schedule();
9683 }
9684
9685 this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta);
9686 this._signal("change", delta);
9687 };
9688 this.setValue = function(text) {
9689 this.doc.setValue(text);
9690 this.selection.moveTo(0, 0);
9691
9692 this.$resetRowCache(0);
9693 this.$deltas = [];
9694 this.$deltasDoc = [];
9695 this.$deltasFold = [];
9696 this.setUndoManager(this.$undoManager);
9697 this.getUndoManager().reset();
9698 };
9699 this.getValue =
9700 this.toString = function() {
9701 return this.doc.getValue();
9702 };
9703 this.getSelection = function() {
9704 return this.selection;
9705 };
9706 this.getState = function(row) {
9707 return this.bgTokenizer.getState(row);
9708 };
9709 this.getTokens = function(row) {
9710 return this.bgTokenizer.getTokens(row);
9711 };
9712 this.getTokenAt = function(row, column) {
9713 var tokens = this.bgTokenizer.getTokens(row);
9714 var token, c = 0;
9715 if (column == null) {
9716 var i = tokens.length - 1;
9717 c = this.getLine(row).length;
9718 } else {
9719 for (var i = 0; i < tokens.length; i++) {
9720 c += tokens[i].value.length;
9721 if (c >= column)
9722 break;
9723 }
9724 }
9725 token = tokens[i];
9726 if (!token)
9727 return null;
9728 token.index = i;
9729 token.start = c - token.value.length;
9730 return token;
9731 };
9732 this.setUndoManager = function(undoManager) {
9733 this.$undoManager = undoManager;
9734 this.$deltas = [];
9735 this.$deltasDoc = [];
9736 this.$deltasFold = [];
9737
9738 if (this.$informUndoManager)
9739 this.$informUndoManager.cancel();
9740
9741 if (undoManager) {
9742 var self = this;
9743
9744 this.$syncInformUndoManager = function() {
9745 self.$informUndoManager.cancel();
9746
9747 if (self.$deltasFold.length) {
9748 self.$deltas.push({
9749 group: "fold",
9750 deltas: self.$deltasFold
9751 });
9752 self.$deltasFold = [];
9753 }
9754
9755 if (self.$deltasDoc.length) {
9756 self.$deltas.push({
9757 group: "doc",
9758 deltas: self.$deltasDoc
9759 });
9760 self.$deltasDoc = [];
9761 }
9762
9763 if (self.$deltas.length > 0) {
9764 undoManager.execute({
9765 action: "aceupdate",
9766 args: [self.$deltas, self],
9767 merge: self.mergeUndoDeltas
9768 });
9769 }
9770 self.mergeUndoDeltas = false;
9771 self.$deltas = [];
9772 };
9773 this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);
9774 }
9775 };
9776 this.markUndoGroup = function() {
9777 if (this.$syncInformUndoManager)
9778 this.$syncInformUndoManager();
9779 };
9780
9781 this.$defaultUndoManager = {
9782 undo: function() {},
9783 redo: function() {},
9784 reset: function() {}
9785 };
9786 this.getUndoManager = function() {
9787 return this.$undoManager || this.$defaultUndoManager;
9788 };
9789 this.getTabString = function() {
9790 if (this.getUseSoftTabs()) {
9791 return lang.stringRepeat(" ", this.getTabSize());
9792 } else {
9793 return "\t";
9794 }
9795 };
9796 this.setUseSoftTabs = function(val) {
9797 this.setOption("useSoftTabs", val);
9798 };
9799 this.getUseSoftTabs = function() {
9800 return this.$useSoftTabs && !this.$mode.$indentWithTabs;
9801 };
9802 this.setTabSize = function(tabSize) {
9803 this.setOption("tabSize", tabSize);
9804 };
9805 this.getTabSize = function() {
9806 return this.$tabSize;
9807 };
9808 this.isTabStop = function(position) {
9809 return this.$useSoftTabs && (position.column % this.$tabSize === 0);
9810 };
9811 this.setNavigateWithinSoftTabs = function (navigateWithinSoftTabs) {
9812 this.setOption("navigateWithinSoftTabs", navigateWithinSoftTabs);
9813 };
9814 this.getNavigateWithinSoftTabs = function() {
9815 return this.$navigateWithinSoftTabs;
9816 };
9817
9818 this.$overwrite = false;
9819 this.setOverwrite = function(overwrite) {
9820 this.setOption("overwrite", overwrite);
9821 };
9822 this.getOverwrite = function() {
9823 return this.$overwrite;
9824 };
9825 this.toggleOverwrite = function() {
9826 this.setOverwrite(!this.$overwrite);
9827 };
9828 this.addGutterDecoration = function(row, className) {
9829 if (!this.$decorations[row])
9830 this.$decorations[row] = "";
9831 this.$decorations[row] += " " + className;
9832 this._signal("changeBreakpoint", {});
9833 };
9834 this.removeGutterDecoration = function(row, className) {
9835 this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
9836 this._signal("changeBreakpoint", {});
9837 };
9838 this.getBreakpoints = function() {
9839 return this.$breakpoints;
9840 };
9841 this.setBreakpoints = function(rows) {
9842 this.$breakpoints = [];
9843 for (var i=0; i<rows.length; i++) {
9844 this.$breakpoints[rows[i]] = "ace_breakpoint";
9845 }
9846 this._signal("changeBreakpoint", {});
9847 };
9848 this.clearBreakpoints = function() {
9849 this.$breakpoints = [];
9850 this._signal("changeBreakpoint", {});
9851 };
9852 this.setBreakpoint = function(row, className) {
9853 if (className === undefined)
9854 className = "ace_breakpoint";
9855 if (className)
9856 this.$breakpoints[row] = className;
9857 else
9858 delete this.$breakpoints[row];
9859 this._signal("changeBreakpoint", {});
9860 };
9861 this.clearBreakpoint = function(row) {
9862 delete this.$breakpoints[row];
9863 this._signal("changeBreakpoint", {});
9864 };
9865 this.addMarker = function(range, clazz, type, inFront) {
9866 var id = this.$markerId++;
9867
9868 var marker = {
9869 range : range,
9870 type : type || "line",
9871 renderer: typeof type == "function" ? type : null,
9872 clazz : clazz,
9873 inFront: !!inFront,
9874 id: id
9875 };
9876
9877 if (inFront) {
9878 this.$frontMarkers[id] = marker;
9879 this._signal("changeFrontMarker");
9880 } else {
9881 this.$backMarkers[id] = marker;
9882 this._signal("changeBackMarker");
9883 }
9884
9885 return id;
9886 };
9887 this.addDynamicMarker = function(marker, inFront) {
9888 if (!marker.update)
9889 return;
9890 var id = this.$markerId++;
9891 marker.id = id;
9892 marker.inFront = !!inFront;
9893
9894 if (inFront) {
9895 this.$frontMarkers[id] = marker;
9896 this._signal("changeFrontMarker");
9897 } else {
9898 this.$backMarkers[id] = marker;
9899 this._signal("changeBackMarker");
9900 }
9901
9902 return marker;
9903 };
9904 this.removeMarker = function(markerId) {
9905 var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
9906 if (!marker)
9907 return;
9908
9909 var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
9910 if (marker) {
9911 delete (markers[markerId]);
9912 this._signal(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
9913 }
9914 };
9915 this.getMarkers = function(inFront) {
9916 return inFront ? this.$frontMarkers : this.$backMarkers;
9917 };
9918
9919 this.highlight = function(re) {
9920 if (!this.$searchHighlight) {
9921 var highlight = new SearchHighlight(null, "ace_selected-word", "text");
9922 this.$searchHighlight = this.addDynamicMarker(highlight);
9923 }
9924 this.$searchHighlight.setRegexp(re);
9925 };
9926 this.highlightLines = function(startRow, endRow, clazz, inFront) {
9927 if (typeof endRow != "number") {
9928 clazz = endRow;
9929 endRow = startRow;
9930 }
9931 if (!clazz)
9932 clazz = "ace_step";
9933
9934 var range = new Range(startRow, 0, endRow, Infinity);
9935 range.id = this.addMarker(range, clazz, "fullLine", inFront);
9936 return range;
9937 };
9938 this.setAnnotations = function(annotations) {
9939 this.$annotations = annotations;
9940 this._signal("changeAnnotation", {});
9941 };
9942 this.getAnnotations = function() {
9943 return this.$annotations || [];
9944 };
9945 this.clearAnnotations = function() {
9946 this.setAnnotations([]);
9947 };
9948 this.$detectNewLine = function(text) {
9949 var match = text.match(/^.*?(\r?\n)/m);
9950 if (match) {
9951 this.$autoNewLine = match[1];
9952 } else {
9953 this.$autoNewLine = "\n";
9954 }
9955 };
9956 this.getWordRange = function(row, column) {
9957 var line = this.getLine(row);
9958
9959 var inToken = false;
9960 if (column > 0)
9961 inToken = !!line.charAt(column - 1).match(this.tokenRe);
9962
9963 if (!inToken)
9964 inToken = !!line.charAt(column).match(this.tokenRe);
9965
9966 if (inToken)
9967 var re = this.tokenRe;
9968 else if (/^\s+$/.test(line.slice(column-1, column+1)))
9969 var re = /\s/;
9970 else
9971 var re = this.nonTokenRe;
9972
9973 var start = column;
9974 if (start > 0) {
9975 do {
9976 start--;
9977 }
9978 while (start >= 0 && line.charAt(start).match(re));
9979 start++;
9980 }
9981
9982 var end = column;
9983 while (end < line.length && line.charAt(end).match(re)) {
9984 end++;
9985 }
9986
9987 return new Range(row, start, row, end);
9988 };
9989 this.getAWordRange = function(row, column) {
9990 var wordRange = this.getWordRange(row, column);
9991 var line = this.getLine(wordRange.end.row);
9992
9993 while (line.charAt(wordRange.end.column).match(/[ \t]/)) {
9994 wordRange.end.column += 1;
9995 }
9996 return wordRange;
9997 };
9998 this.setNewLineMode = function(newLineMode) {
9999 this.doc.setNewLineMode(newLineMode);
10000 };
10001 this.getNewLineMode = function() {
10002 return this.doc.getNewLineMode();
10003 };
10004 this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); };
10005 this.getUseWorker = function() { return this.$useWorker; };
10006 this.onReloadTokenizer = function(e) {
10007 var rows = e.data;
10008 this.bgTokenizer.start(rows.first);
10009 this._signal("tokenizerUpdate", e);
10010 };
10011
10012 this.$modes = {};
10013 this.$mode = null;
10014 this.$modeId = null;
10015 this.setMode = function(mode, cb) {
10016 if (mode && typeof mode === "object") {
10017 if (mode.getTokenizer)
10018 return this.$onChangeMode(mode);
10019 var options = mode;
10020 var path = options.path;
10021 } else {
10022 path = mode || "ace/mode/text";
10023 }
10024 if (!this.$modes["ace/mode/text"])
10025 this.$modes["ace/mode/text"] = new TextMode();
10026
10027 if (this.$modes[path] && !options) {
10028 this.$onChangeMode(this.$modes[path]);
10029 cb && cb();
10030 return;
10031 }
10032 this.$modeId = path;
10033 config.loadModule(["mode", path], function(m) {
10034 if (this.$modeId !== path)
10035 return cb && cb();
10036 if (this.$modes[path] && !options) {
10037 this.$onChangeMode(this.$modes[path]);
10038 } else if (m && m.Mode) {
10039 m = new m.Mode(options);
10040 if (!options) {
10041 this.$modes[path] = m;
10042 m.$id = path;
10043 }
10044 this.$onChangeMode(m);
10045 }
10046 cb && cb();
10047 }.bind(this));
10048 if (!this.$mode)
10049 this.$onChangeMode(this.$modes["ace/mode/text"], true);
10050 };
10051
10052 this.$onChangeMode = function(mode, $isPlaceholder) {
10053 if (!$isPlaceholder)
10054 this.$modeId = mode.$id;
10055 if (this.$mode === mode)
10056 return;
10057
10058 this.$mode = mode;
10059
10060 this.$stopWorker();
10061
10062 if (this.$useWorker)
10063 this.$startWorker();
10064
10065 var tokenizer = mode.getTokenizer();
10066
10067 if(tokenizer.addEventListener !== undefined) {
10068 var onReloadTokenizer = this.onReloadTokenizer.bind(this);
10069 tokenizer.addEventListener("update", onReloadTokenizer);
10070 }
10071
10072 if (!this.bgTokenizer) {
10073 this.bgTokenizer = new BackgroundTokenizer(tokenizer);
10074 var _self = this;
10075 this.bgTokenizer.addEventListener("update", function(e) {
10076 _self._signal("tokenizerUpdate", e);
10077 });
10078 } else {
10079 this.bgTokenizer.setTokenizer(tokenizer);
10080 }
10081
10082 this.bgTokenizer.setDocument(this.getDocument());
10083
10084 this.tokenRe = mode.tokenRe;
10085 this.nonTokenRe = mode.nonTokenRe;
10086
10087
10088 if (!$isPlaceholder) {
10089 if (mode.attachToSession)
10090 mode.attachToSession(this);
10091 this.$options.wrapMethod.set.call(this, this.$wrapMethod);
10092 this.$setFolding(mode.foldingRules);
10093 this.bgTokenizer.start(0);
10094 this._emit("changeMode");
10095 }
10096 };
10097
10098 this.$stopWorker = function() {
10099 if (this.$worker) {
10100 this.$worker.terminate();
10101 this.$worker = null;
10102 }
10103 };
10104
10105 this.$startWorker = function() {
10106 try {
10107 this.$worker = this.$mode.createWorker(this);
10108 } catch (e) {
10109 config.warn("Could not load worker", e);
10110 this.$worker = null;
10111 }
10112 };
10113 this.getMode = function() {
10114 return this.$mode;
10115 };
10116
10117 this.$scrollTop = 0;
10118 this.setScrollTop = function(scrollTop) {
10119 if (this.$scrollTop === scrollTop || isNaN(scrollTop))
10120 return;
10121
10122 this.$scrollTop = scrollTop;
10123 this._signal("changeScrollTop", scrollTop);
10124 };
10125 this.getScrollTop = function() {
10126 return this.$scrollTop;
10127 };
10128
10129 this.$scrollLeft = 0;
10130 this.setScrollLeft = function(scrollLeft) {
10131 if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
10132 return;
10133
10134 this.$scrollLeft = scrollLeft;
10135 this._signal("changeScrollLeft", scrollLeft);
10136 };
10137 this.getScrollLeft = function() {
10138 return this.$scrollLeft;
10139 };
10140 this.getScreenWidth = function() {
10141 this.$computeWidth();
10142 if (this.lineWidgets)
10143 return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);
10144 return this.screenWidth;
10145 };
10146
10147 this.getLineWidgetMaxWidth = function() {
10148 if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth;
10149 var width = 0;
10150 this.lineWidgets.forEach(function(w) {
10151 if (w && w.screenWidth > width)
10152 width = w.screenWidth;
10153 });
10154 return this.lineWidgetWidth = width;
10155 };
10156
10157 this.$computeWidth = function(force) {
10158 if (this.$modified || force) {
10159 this.$modified = false;
10160
10161 if (this.$useWrapMode)
10162 return this.screenWidth = this.$wrapLimit;
10163
10164 var lines = this.doc.getAllLines();
10165 var cache = this.$rowLengthCache;
10166 var longestScreenLine = 0;
10167 var foldIndex = 0;
10168 var foldLine = this.$foldData[foldIndex];
10169 var foldStart = foldLine ? foldLine.start.row : Infinity;
10170 var len = lines.length;
10171
10172 for (var i = 0; i < len; i++) {
10173 if (i > foldStart) {
10174 i = foldLine.end.row + 1;
10175 if (i >= len)
10176 break;
10177 foldLine = this.$foldData[foldIndex++];
10178 foldStart = foldLine ? foldLine.start.row : Infinity;
10179 }
10180
10181 if (cache[i] == null)
10182 cache[i] = this.$getStringScreenWidth(lines[i])[0];
10183
10184 if (cache[i] > longestScreenLine)
10185 longestScreenLine = cache[i];
10186 }
10187 this.screenWidth = longestScreenLine;
10188 }
10189 };
10190 this.getLine = function(row) {
10191 return this.doc.getLine(row);
10192 };
10193 this.getLines = function(firstRow, lastRow) {
10194 return this.doc.getLines(firstRow, lastRow);
10195 };
10196 this.getLength = function() {
10197 return this.doc.getLength();
10198 };
10199 this.getTextRange = function(range) {
10200 return this.doc.getTextRange(range || this.selection.getRange());
10201 };
10202 this.insert = function(position, text) {
10203 return this.doc.insert(position, text);
10204 };
10205 this.remove = function(range) {
10206 return this.doc.remove(range);
10207 };
10208 this.removeFullLines = function(firstRow, lastRow){
10209 return this.doc.removeFullLines(firstRow, lastRow);
10210 };
10211 this.undoChanges = function(deltas, dontSelect) {
10212 if (!deltas.length)
10213 return;
10214
10215 this.$fromUndo = true;
10216 var lastUndoRange = null;
10217 for (var i = deltas.length - 1; i != -1; i--) {
10218 var delta = deltas[i];
10219 if (delta.group == "doc") {
10220 this.doc.revertDeltas(delta.deltas);
10221 lastUndoRange =
10222 this.$getUndoSelection(delta.deltas, true, lastUndoRange);
10223 } else {
10224 delta.deltas.forEach(function(foldDelta) {
10225 this.addFolds(foldDelta.folds);
10226 }, this);
10227 }
10228 }
10229 this.$fromUndo = false;
10230 lastUndoRange &&
10231 this.$undoSelect &&
10232 !dontSelect &&
10233 this.selection.setSelectionRange(lastUndoRange);
10234 return lastUndoRange;
10235 };
10236 this.redoChanges = function(deltas, dontSelect) {
10237 if (!deltas.length)
10238 return;
10239
10240 this.$fromUndo = true;
10241 var lastUndoRange = null;
10242 for (var i = 0; i < deltas.length; i++) {
10243 var delta = deltas[i];
10244 if (delta.group == "doc") {
10245 this.doc.applyDeltas(delta.deltas);
10246 lastUndoRange =
10247 this.$getUndoSelection(delta.deltas, false, lastUndoRange);
10248 }
10249 }
10250 this.$fromUndo = false;
10251 lastUndoRange &&
10252 this.$undoSelect &&
10253 !dontSelect &&
10254 this.selection.setSelectionRange(lastUndoRange);
10255 return lastUndoRange;
10256 };
10257 this.setUndoSelect = function(enable) {
10258 this.$undoSelect = enable;
10259 };
10260
10261 this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
10262 function isInsert(delta) {
10263 return isUndo ? delta.action !== "insert" : delta.action === "insert";
10264 }
10265
10266 var delta = deltas[0];
10267 var range, point;
10268 if (isInsert(delta)) {
10269 range = Range.fromPoints(delta.start, delta.end);
10270 } else {
10271 range = Range.fromPoints(delta.start, delta.start);
10272 }
10273
10274 for (var i = 1; i < deltas.length; i++) {
10275 delta = deltas[i];
10276 if (isInsert(delta)) {
10277 point = delta.start;
10278 if (range.compare(point.row, point.column) == -1) {
10279 range.setStart(point);
10280 }
10281 point = delta.end;
10282 if (range.compare(point.row, point.column) == 1) {
10283 range.setEnd(point);
10284 }
10285 } else {
10286 point = delta.start;
10287 if (range.compare(point.row, point.column) == -1) {
10288 range = Range.fromPoints(delta.start, delta.start);
10289 }
10290 }
10291 }
10292 if (lastUndoRange != null) {
10293 if (Range.comparePoints(lastUndoRange.start, range.start) === 0) {
10294 lastUndoRange.start.column += range.end.column - range.start.column;
10295 lastUndoRange.end.column += range.end.column - range.start.column;
10296 }
10297
10298 var cmp = lastUndoRange.compareRange(range);
10299 if (cmp == 1) {
10300 range.setStart(lastUndoRange.start);
10301 } else if (cmp == -1) {
10302 range.setEnd(lastUndoRange.end);
10303 }
10304 }
10305
10306 return range;
10307 };
10308 this.replace = function(range, text) {
10309 return this.doc.replace(range, text);
10310 };
10311 this.moveText = function(fromRange, toPosition, copy) {
10312 var text = this.getTextRange(fromRange);
10313 var folds = this.getFoldsInRange(fromRange);
10314
10315 var toRange = Range.fromPoints(toPosition, toPosition);
10316 if (!copy) {
10317 this.remove(fromRange);
10318 var rowDiff = fromRange.start.row - fromRange.end.row;
10319 var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
10320 if (collDiff) {
10321 if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
10322 toRange.start.column += collDiff;
10323 if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
10324 toRange.end.column += collDiff;
10325 }
10326 if (rowDiff && toRange.start.row >= fromRange.end.row) {
10327 toRange.start.row += rowDiff;
10328 toRange.end.row += rowDiff;
10329 }
10330 }
10331
10332 toRange.end = this.insert(toRange.start, text);
10333 if (folds.length) {
10334 var oldStart = fromRange.start;
10335 var newStart = toRange.start;
10336 var rowDiff = newStart.row - oldStart.row;
10337 var collDiff = newStart.column - oldStart.column;
10338 this.addFolds(folds.map(function(x) {
10339 x = x.clone();
10340 if (x.start.row == oldStart.row)
10341 x.start.column += collDiff;
10342 if (x.end.row == oldStart.row)
10343 x.end.column += collDiff;
10344 x.start.row += rowDiff;
10345 x.end.row += rowDiff;
10346 return x;
10347 }));
10348 }
10349
10350 return toRange;
10351 };
10352 this.indentRows = function(startRow, endRow, indentString) {
10353 indentString = indentString.replace(/\t/g, this.getTabString());
10354 for (var row=startRow; row<=endRow; row++)
10355 this.doc.insertInLine({row: row, column: 0}, indentString);
10356 };
10357 this.outdentRows = function (range) {
10358 var rowRange = range.collapseRows();
10359 var deleteRange = new Range(0, 0, 0, 0);
10360 var size = this.getTabSize();
10361
10362 for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
10363 var line = this.getLine(i);
10364
10365 deleteRange.start.row = i;
10366 deleteRange.end.row = i;
10367 for (var j = 0; j < size; ++j)
10368 if (line.charAt(j) != ' ')
10369 break;
10370 if (j < size && line.charAt(j) == '\t') {
10371 deleteRange.start.column = j;
10372 deleteRange.end.column = j + 1;
10373 } else {
10374 deleteRange.start.column = 0;
10375 deleteRange.end.column = j;
10376 }
10377 this.remove(deleteRange);
10378 }
10379 };
10380
10381 this.$moveLines = function(firstRow, lastRow, dir) {
10382 firstRow = this.getRowFoldStart(firstRow);
10383 lastRow = this.getRowFoldEnd(lastRow);
10384 if (dir < 0) {
10385 var row = this.getRowFoldStart(firstRow + dir);
10386 if (row < 0) return 0;
10387 var diff = row-firstRow;
10388 } else if (dir > 0) {
10389 var row = this.getRowFoldEnd(lastRow + dir);
10390 if (row > this.doc.getLength()-1) return 0;
10391 var diff = row-lastRow;
10392 } else {
10393 firstRow = this.$clipRowToDocument(firstRow);
10394 lastRow = this.$clipRowToDocument(lastRow);
10395 var diff = lastRow - firstRow + 1;
10396 }
10397
10398 var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
10399 var folds = this.getFoldsInRange(range).map(function(x){
10400 x = x.clone();
10401 x.start.row += diff;
10402 x.end.row += diff;
10403 return x;
10404 });
10405
10406 var lines = dir == 0
10407 ? this.doc.getLines(firstRow, lastRow)
10408 : this.doc.removeFullLines(firstRow, lastRow);
10409 this.doc.insertFullLines(firstRow+diff, lines);
10410 folds.length && this.addFolds(folds);
10411 return diff;
10412 };
10413 this.moveLinesUp = function(firstRow, lastRow) {
10414 return this.$moveLines(firstRow, lastRow, -1);
10415 };
10416 this.moveLinesDown = function(firstRow, lastRow) {
10417 return this.$moveLines(firstRow, lastRow, 1);
10418 };
10419 this.duplicateLines = function(firstRow, lastRow) {
10420 return this.$moveLines(firstRow, lastRow, 0);
10421 };
10422
10423
10424 this.$clipRowToDocument = function(row) {
10425 return Math.max(0, Math.min(row, this.doc.getLength()-1));
10426 };
10427
10428 this.$clipColumnToRow = function(row, column) {
10429 if (column < 0)
10430 return 0;
10431 return Math.min(this.doc.getLine(row).length, column);
10432 };
10433
10434
10435 this.$clipPositionToDocument = function(row, column) {
10436 column = Math.max(0, column);
10437
10438 if (row < 0) {
10439 row = 0;
10440 column = 0;
10441 } else {
10442 var len = this.doc.getLength();
10443 if (row >= len) {
10444 row = len - 1;
10445 column = this.doc.getLine(len-1).length;
10446 } else {
10447 column = Math.min(this.doc.getLine(row).length, column);
10448 }
10449 }
10450
10451 return {
10452 row: row,
10453 column: column
10454 };
10455 };
10456
10457 this.$clipRangeToDocument = function(range) {
10458 if (range.start.row < 0) {
10459 range.start.row = 0;
10460 range.start.column = 0;
10461 } else {
10462 range.start.column = this.$clipColumnToRow(
10463 range.start.row,
10464 range.start.column
10465 );
10466 }
10467
10468 var len = this.doc.getLength() - 1;
10469 if (range.end.row > len) {
10470 range.end.row = len;
10471 range.end.column = this.doc.getLine(len).length;
10472 } else {
10473 range.end.column = this.$clipColumnToRow(
10474 range.end.row,
10475 range.end.column
10476 );
10477 }
10478 return range;
10479 };
10480 this.$wrapLimit = 80;
10481 this.$useWrapMode = false;
10482 this.$wrapLimitRange = {
10483 min : null,
10484 max : null
10485 };
10486 this.setUseWrapMode = function(useWrapMode) {
10487 if (useWrapMode != this.$useWrapMode) {
10488 this.$useWrapMode = useWrapMode;
10489 this.$modified = true;
10490 this.$resetRowCache(0);
10491 if (useWrapMode) {
10492 var len = this.getLength();
10493 this.$wrapData = Array(len);
10494 this.$updateWrapData(0, len - 1);
10495 }
10496
10497 this._signal("changeWrapMode");
10498 }
10499 };
10500 this.getUseWrapMode = function() {
10501 return this.$useWrapMode;
10502 };
10503 this.setWrapLimitRange = function(min, max) {
10504 if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
10505 this.$wrapLimitRange = { min: min, max: max };
10506 this.$modified = true;
10507 this.$bidiHandler.markAsDirty();
10508 if (this.$useWrapMode)
10509 this._signal("changeWrapMode");
10510 }
10511 };
10512 this.adjustWrapLimit = function(desiredLimit, $printMargin) {
10513 var limits = this.$wrapLimitRange;
10514 if (limits.max < 0)
10515 limits = {min: $printMargin, max: $printMargin};
10516 var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max);
10517 if (wrapLimit != this.$wrapLimit && wrapLimit > 1) {
10518 this.$wrapLimit = wrapLimit;
10519 this.$modified = true;
10520 if (this.$useWrapMode) {
10521 this.$updateWrapData(0, this.getLength() - 1);
10522 this.$resetRowCache(0);
10523 this._signal("changeWrapLimit");
10524 }
10525 return true;
10526 }
10527 return false;
10528 };
10529
10530 this.$constrainWrapLimit = function(wrapLimit, min, max) {
10531 if (min)
10532 wrapLimit = Math.max(min, wrapLimit);
10533
10534 if (max)
10535 wrapLimit = Math.min(max, wrapLimit);
10536
10537 return wrapLimit;
10538 };
10539 this.getWrapLimit = function() {
10540 return this.$wrapLimit;
10541 };
10542 this.setWrapLimit = function (limit) {
10543 this.setWrapLimitRange(limit, limit);
10544 };
10545 this.getWrapLimitRange = function() {
10546 return {
10547 min : this.$wrapLimitRange.min,
10548 max : this.$wrapLimitRange.max
10549 };
10550 };
10551
10552 this.$updateInternalDataOnChange = function(delta) {
10553 var useWrapMode = this.$useWrapMode;
10554 var action = delta.action;
10555 var start = delta.start;
10556 var end = delta.end;
10557 var firstRow = start.row;
10558 var lastRow = end.row;
10559 var len = lastRow - firstRow;
10560 var removedFolds = null;
10561
10562 this.$updating = true;
10563 if (len != 0) {
10564 if (action === "remove") {
10565 this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len);
10566
10567 var foldLines = this.$foldData;
10568 removedFolds = this.getFoldsInRange(delta);
10569 this.removeFolds(removedFolds);
10570
10571 var foldLine = this.getFoldLine(end.row);
10572 var idx = 0;
10573 if (foldLine) {
10574 foldLine.addRemoveChars(end.row, end.column, start.column - end.column);
10575 foldLine.shiftRow(-len);
10576
10577 var foldLineBefore = this.getFoldLine(firstRow);
10578 if (foldLineBefore && foldLineBefore !== foldLine) {
10579 foldLineBefore.merge(foldLine);
10580 foldLine = foldLineBefore;
10581 }
10582 idx = foldLines.indexOf(foldLine) + 1;
10583 }
10584
10585 for (idx; idx < foldLines.length; idx++) {
10586 var foldLine = foldLines[idx];
10587 if (foldLine.start.row >= end.row) {
10588 foldLine.shiftRow(-len);
10589 }
10590 }
10591
10592 lastRow = firstRow;
10593 } else {
10594 var args = Array(len);
10595 args.unshift(firstRow, 0);
10596 var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache;
10597 arr.splice.apply(arr, args);
10598 var foldLines = this.$foldData;
10599 var foldLine = this.getFoldLine(firstRow);
10600 var idx = 0;
10601 if (foldLine) {
10602 var cmp = foldLine.range.compareInside(start.row, start.column);
10603 if (cmp == 0) {
10604 foldLine = foldLine.split(start.row, start.column);
10605 if (foldLine) {
10606 foldLine.shiftRow(len);
10607 foldLine.addRemoveChars(lastRow, 0, end.column - start.column);
10608 }
10609 } else
10610 if (cmp == -1) {
10611 foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
10612 foldLine.shiftRow(len);
10613 }
10614 idx = foldLines.indexOf(foldLine) + 1;
10615 }
10616
10617 for (idx; idx < foldLines.length; idx++) {
10618 var foldLine = foldLines[idx];
10619 if (foldLine.start.row >= firstRow) {
10620 foldLine.shiftRow(len);
10621 }
10622 }
10623 }
10624 } else {
10625 len = Math.abs(delta.start.column - delta.end.column);
10626 if (action === "remove") {
10627 removedFolds = this.getFoldsInRange(delta);
10628 this.removeFolds(removedFolds);
10629
10630 len = -len;
10631 }
10632 var foldLine = this.getFoldLine(firstRow);
10633 if (foldLine) {
10634 foldLine.addRemoveChars(firstRow, start.column, len);
10635 }
10636 }
10637
10638 if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {
10639 console.error("doc.getLength() and $wrapData.length have to be the same!");
10640 }
10641 this.$updating = false;
10642
10643 if (useWrapMode)
10644 this.$updateWrapData(firstRow, lastRow);
10645 else
10646 this.$updateRowLengthCache(firstRow, lastRow);
10647
10648 return removedFolds;
10649 };
10650
10651 this.$updateRowLengthCache = function(firstRow, lastRow, b) {
10652 this.$rowLengthCache[firstRow] = null;
10653 this.$rowLengthCache[lastRow] = null;
10654 };
10655
10656 this.$updateWrapData = function(firstRow, lastRow) {
10657 var lines = this.doc.getAllLines();
10658 var tabSize = this.getTabSize();
10659 var wrapData = this.$wrapData;
10660 var wrapLimit = this.$wrapLimit;
10661 var tokens;
10662 var foldLine;
10663
10664 var row = firstRow;
10665 lastRow = Math.min(lastRow, lines.length - 1);
10666 while (row <= lastRow) {
10667 foldLine = this.getFoldLine(row, foldLine);
10668 if (!foldLine) {
10669 tokens = this.$getDisplayTokens(lines[row]);
10670 wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
10671 row ++;
10672 } else {
10673 tokens = [];
10674 foldLine.walk(function(placeholder, row, column, lastColumn) {
10675 var walkTokens;
10676 if (placeholder != null) {
10677 walkTokens = this.$getDisplayTokens(
10678 placeholder, tokens.length);
10679 walkTokens[0] = PLACEHOLDER_START;
10680 for (var i = 1; i < walkTokens.length; i++) {
10681 walkTokens[i] = PLACEHOLDER_BODY;
10682 }
10683 } else {
10684 walkTokens = this.$getDisplayTokens(
10685 lines[row].substring(lastColumn, column),
10686 tokens.length);
10687 }
10688 tokens = tokens.concat(walkTokens);
10689 }.bind(this),
10690 foldLine.end.row,
10691 lines[foldLine.end.row].length + 1
10692 );
10693
10694 wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
10695 row = foldLine.end.row + 1;
10696 }
10697 }
10698 };
10699 var CHAR = 1,
10700 CHAR_EXT = 2,
10701 PLACEHOLDER_START = 3,
10702 PLACEHOLDER_BODY = 4,
10703 PUNCTUATION = 9,
10704 SPACE = 10,
10705 TAB = 11,
10706 TAB_SPACE = 12;
10707
10708
10709 this.$computeWrapSplits = function(tokens, wrapLimit, tabSize) {
10710 if (tokens.length == 0) {
10711 return [];
10712 }
10713
10714 var splits = [];
10715 var displayLength = tokens.length;
10716 var lastSplit = 0, lastDocSplit = 0;
10717
10718 var isCode = this.$wrapAsCode;
10719
10720 var indentedSoftWrap = this.$indentedSoftWrap;
10721 var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8)
10722 || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2);
10723
10724 function getWrapIndent() {
10725 var indentation = 0;
10726 if (maxIndent === 0)
10727 return indentation;
10728 if (indentedSoftWrap) {
10729 for (var i = 0; i < tokens.length; i++) {
10730 var token = tokens[i];
10731 if (token == SPACE)
10732 indentation += 1;
10733 else if (token == TAB)
10734 indentation += tabSize;
10735 else if (token == TAB_SPACE)
10736 continue;
10737 else
10738 break;
10739 }
10740 }
10741 if (isCode && indentedSoftWrap !== false)
10742 indentation += tabSize;
10743 return Math.min(indentation, maxIndent);
10744 }
10745 function addSplit(screenPos) {
10746 var displayed = tokens.slice(lastSplit, screenPos);
10747 var len = displayed.length;
10748 displayed.join("")
10749 .replace(/12/g, function() {
10750 len -= 1;
10751 })
10752 .replace(/2/g, function() {
10753 len -= 1;
10754 });
10755
10756 if (!splits.length) {
10757 indent = getWrapIndent();
10758 splits.indent = indent;
10759 }
10760 lastDocSplit += len;
10761 splits.push(lastDocSplit);
10762 lastSplit = screenPos;
10763 }
10764 var indent = 0;
10765 while (displayLength - lastSplit > wrapLimit - indent) {
10766 var split = lastSplit + wrapLimit - indent;
10767 if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) {
10768 addSplit(split);
10769 continue;
10770 }
10771 if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) {
10772 for (split; split != lastSplit - 1; split--) {
10773 if (tokens[split] == PLACEHOLDER_START) {
10774 break;
10775 }
10776 }
10777 if (split > lastSplit) {
10778 addSplit(split);
10779 continue;
10780 }
10781 split = lastSplit + wrapLimit;
10782 for (split; split < tokens.length; split++) {
10783 if (tokens[split] != PLACEHOLDER_BODY) {
10784 break;
10785 }
10786 }
10787 if (split == tokens.length) {
10788 break; // Breaks the while-loop.
10789 }
10790 addSplit(split);
10791 continue;
10792 }
10793 var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1);
10794 while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
10795 split --;
10796 }
10797 if (isCode) {
10798 while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
10799 split --;
10800 }
10801 while (split > minSplit && tokens[split] == PUNCTUATION) {
10802 split --;
10803 }
10804 } else {
10805 while (split > minSplit && tokens[split] < SPACE) {
10806 split --;
10807 }
10808 }
10809 if (split > minSplit) {
10810 addSplit(++split);
10811 continue;
10812 }
10813 split = lastSplit + wrapLimit;
10814 if (tokens[split] == CHAR_EXT)
10815 split--;
10816 addSplit(split - indent);
10817 }
10818 return splits;
10819 };
10820 this.$getDisplayTokens = function(str, offset) {
10821 var arr = [];
10822 var tabSize;
10823 offset = offset || 0;
10824
10825 for (var i = 0; i < str.length; i++) {
10826 var c = str.charCodeAt(i);
10827 if (c == 9) {
10828 tabSize = this.getScreenTabSize(arr.length + offset);
10829 arr.push(TAB);
10830 for (var n = 1; n < tabSize; n++) {
10831 arr.push(TAB_SPACE);
10832 }
10833 }
10834 else if (c == 32) {
10835 arr.push(SPACE);
10836 } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {
10837 arr.push(PUNCTUATION);
10838 }
10839 else if (c >= 0x1100 && isFullWidth(c)) {
10840 arr.push(CHAR, CHAR_EXT);
10841 } else {
10842 arr.push(CHAR);
10843 }
10844 }
10845 return arr;
10846 };
10847 this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
10848 if (maxScreenColumn == 0)
10849 return [0, 0];
10850 if (maxScreenColumn == null)
10851 maxScreenColumn = Infinity;
10852 screenColumn = screenColumn || 0;
10853
10854 var c, column;
10855 for (column = 0; column < str.length; column++) {
10856 c = str.charCodeAt(column);
10857 if (c == 9) {
10858 screenColumn += this.getScreenTabSize(screenColumn);
10859 }
10860 else if (c >= 0x1100 && isFullWidth(c)) {
10861 screenColumn += 2;
10862 } else {
10863 screenColumn += 1;
10864 }
10865 if (screenColumn > maxScreenColumn) {
10866 break;
10867 }
10868 }
10869
10870 return [screenColumn, column];
10871 };
10872
10873 this.lineWidgets = null;
10874 this.getRowLength = function(row) {
10875 if (this.lineWidgets)
10876 var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
10877 else
10878 h = 0;
10879 if (!this.$useWrapMode || !this.$wrapData[row]) {
10880 return 1 + h;
10881 } else {
10882 return this.$wrapData[row].length + 1 + h;
10883 }
10884 };
10885 this.getRowLineCount = function(row) {
10886 if (!this.$useWrapMode || !this.$wrapData[row]) {
10887 return 1;
10888 } else {
10889 return this.$wrapData[row].length + 1;
10890 }
10891 };
10892
10893 this.getRowWrapIndent = function(screenRow) {
10894 if (this.$useWrapMode) {
10895 var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
10896 var splits = this.$wrapData[pos.row];
10897 return splits.length && splits[0] < pos.column ? splits.indent : 0;
10898 } else {
10899 return 0;
10900 }
10901 };
10902 this.getScreenLastRowColumn = function(screenRow) {
10903 var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
10904 return this.documentToScreenColumn(pos.row, pos.column);
10905 };
10906 this.getDocumentLastRowColumn = function(docRow, docColumn) {
10907 var screenRow = this.documentToScreenRow(docRow, docColumn);
10908 return this.getScreenLastRowColumn(screenRow);
10909 };
10910 this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
10911 var screenRow = this.documentToScreenRow(docRow, docColumn);
10912 return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
10913 };
10914 this.getRowSplitData = function(row) {
10915 if (!this.$useWrapMode) {
10916 return undefined;
10917 } else {
10918 return this.$wrapData[row];
10919 }
10920 };
10921 this.getScreenTabSize = function(screenColumn) {
10922 return this.$tabSize - screenColumn % this.$tabSize;
10923 };
10924
10925
10926 this.screenToDocumentRow = function(screenRow, screenColumn) {
10927 return this.screenToDocumentPosition(screenRow, screenColumn).row;
10928 };
10929
10930
10931 this.screenToDocumentColumn = function(screenRow, screenColumn) {
10932 return this.screenToDocumentPosition(screenRow, screenColumn).column;
10933 };
10934 this.screenToDocumentPosition = function(screenRow, screenColumn, offsetX) {
10935 if (screenRow < 0)
10936 return {row: 0, column: 0};
10937
10938 var line;
10939 var docRow = 0;
10940 var docColumn = 0;
10941 var column;
10942 var row = 0;
10943 var rowLength = 0;
10944
10945 var rowCache = this.$screenRowCache;
10946 var i = this.$getRowCacheIndex(rowCache, screenRow);
10947 var l = rowCache.length;
10948 if (l && i >= 0) {
10949 var row = rowCache[i];
10950 var docRow = this.$docRowCache[i];
10951 var doCache = screenRow > rowCache[l - 1];
10952 } else {
10953 var doCache = !l;
10954 }
10955
10956 var maxRow = this.getLength() - 1;
10957 var foldLine = this.getNextFoldLine(docRow);
10958 var foldStart = foldLine ? foldLine.start.row : Infinity;
10959
10960 while (row <= screenRow) {
10961 rowLength = this.getRowLength(docRow);
10962 if (row + rowLength > screenRow || docRow >= maxRow) {
10963 break;
10964 } else {
10965 row += rowLength;
10966 docRow++;
10967 if (docRow > foldStart) {
10968 docRow = foldLine.end.row+1;
10969 foldLine = this.getNextFoldLine(docRow, foldLine);
10970 foldStart = foldLine ? foldLine.start.row : Infinity;
10971 }
10972 }
10973
10974 if (doCache) {
10975 this.$docRowCache.push(docRow);
10976 this.$screenRowCache.push(row);
10977 }
10978 }
10979
10980 if (foldLine && foldLine.start.row <= docRow) {
10981 line = this.getFoldDisplayLine(foldLine);
10982 docRow = foldLine.start.row;
10983 } else if (row + rowLength <= screenRow || docRow > maxRow) {
10984 return {
10985 row: maxRow,
10986 column: this.getLine(maxRow).length
10987 };
10988 } else {
10989 line = this.getLine(docRow);
10990 foldLine = null;
10991 }
10992 var wrapIndent = 0, splitIndex = Math.floor(screenRow - row);
10993 if (this.$useWrapMode) {
10994 var splits = this.$wrapData[docRow];
10995 if (splits) {
10996 column = splits[splitIndex];
10997 if(splitIndex > 0 && splits.length) {
10998 wrapIndent = splits.indent;
10999 docColumn = splits[splitIndex - 1] || splits[splits.length - 1];
11000 line = line.substring(docColumn);
11001 }
11002 }
11003 }
11004
11005 if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex))
11006 screenColumn = this.$bidiHandler.offsetToCol(offsetX);
11007
11008 docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1];
11009 if (this.$useWrapMode && docColumn >= column)
11010 docColumn = column - 1;
11011
11012 if (foldLine)
11013 return foldLine.idxToPosition(docColumn);
11014
11015 return {row: docRow, column: docColumn};
11016 };
11017 this.documentToScreenPosition = function(docRow, docColumn) {
11018 if (typeof docColumn === "undefined")
11019 var pos = this.$clipPositionToDocument(docRow.row, docRow.column);
11020 else
11021 pos = this.$clipPositionToDocument(docRow, docColumn);
11022
11023 docRow = pos.row;
11024 docColumn = pos.column;
11025
11026 var screenRow = 0;
11027 var foldStartRow = null;
11028 var fold = null;
11029 fold = this.getFoldAt(docRow, docColumn, 1);
11030 if (fold) {
11031 docRow = fold.start.row;
11032 docColumn = fold.start.column;
11033 }
11034
11035 var rowEnd, row = 0;
11036
11037
11038 var rowCache = this.$docRowCache;
11039 var i = this.$getRowCacheIndex(rowCache, docRow);
11040 var l = rowCache.length;
11041 if (l && i >= 0) {
11042 var row = rowCache[i];
11043 var screenRow = this.$screenRowCache[i];
11044 var doCache = docRow > rowCache[l - 1];
11045 } else {
11046 var doCache = !l;
11047 }
11048
11049 var foldLine = this.getNextFoldLine(row);
11050 var foldStart = foldLine ?foldLine.start.row :Infinity;
11051
11052 while (row < docRow) {
11053 if (row >= foldStart) {
11054 rowEnd = foldLine.end.row + 1;
11055 if (rowEnd > docRow)
11056 break;
11057 foldLine = this.getNextFoldLine(rowEnd, foldLine);
11058 foldStart = foldLine ?foldLine.start.row :Infinity;
11059 }
11060 else {
11061 rowEnd = row + 1;
11062 }
11063
11064 screenRow += this.getRowLength(row);
11065 row = rowEnd;
11066
11067 if (doCache) {
11068 this.$docRowCache.push(row);
11069 this.$screenRowCache.push(screenRow);
11070 }
11071 }
11072 var textLine = "";
11073 if (foldLine && row >= foldStart) {
11074 textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
11075 foldStartRow = foldLine.start.row;
11076 } else {
11077 textLine = this.getLine(docRow).substring(0, docColumn);
11078 foldStartRow = docRow;
11079 }
11080 var wrapIndent = 0;
11081 if (this.$useWrapMode) {
11082 var wrapRow = this.$wrapData[foldStartRow];
11083 if (wrapRow) {
11084 var screenRowOffset = 0;
11085 while (textLine.length >= wrapRow[screenRowOffset]) {
11086 screenRow ++;
11087 screenRowOffset++;
11088 }
11089 textLine = textLine.substring(
11090 wrapRow[screenRowOffset - 1] || 0, textLine.length
11091 );
11092 wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;
11093 }
11094 }
11095
11096 return {
11097 row: screenRow,
11098 column: wrapIndent + this.$getStringScreenWidth(textLine)[0]
11099 };
11100 };
11101 this.documentToScreenColumn = function(row, docColumn) {
11102 return this.documentToScreenPosition(row, docColumn).column;
11103 };
11104 this.documentToScreenRow = function(docRow, docColumn) {
11105 return this.documentToScreenPosition(docRow, docColumn).row;
11106 };
11107 this.getScreenLength = function() {
11108 var screenRows = 0;
11109 var fold = null;
11110 if (!this.$useWrapMode) {
11111 screenRows = this.getLength();
11112 var foldData = this.$foldData;
11113 for (var i = 0; i < foldData.length; i++) {
11114 fold = foldData[i];
11115 screenRows -= fold.end.row - fold.start.row;
11116 }
11117 } else {
11118 var lastRow = this.$wrapData.length;
11119 var row = 0, i = 0;
11120 var fold = this.$foldData[i++];
11121 var foldStart = fold ? fold.start.row :Infinity;
11122
11123 while (row < lastRow) {
11124 var splits = this.$wrapData[row];
11125 screenRows += splits ? splits.length + 1 : 1;
11126 row ++;
11127 if (row > foldStart) {
11128 row = fold.end.row+1;
11129 fold = this.$foldData[i++];
11130 foldStart = fold ?fold.start.row :Infinity;
11131 }
11132 }
11133 }
11134 if (this.lineWidgets)
11135 screenRows += this.$getWidgetScreenLength();
11136
11137 return screenRows;
11138 };
11139 this.$setFontMetrics = function(fm) {
11140 if (!this.$enableVarChar) return;
11141 this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
11142 if (maxScreenColumn === 0)
11143 return [0, 0];
11144 if (!maxScreenColumn)
11145 maxScreenColumn = Infinity;
11146 screenColumn = screenColumn || 0;
11147
11148 var c, column;
11149 for (column = 0; column < str.length; column++) {
11150 c = str.charAt(column);
11151 if (c === "\t") {
11152 screenColumn += this.getScreenTabSize(screenColumn);
11153 } else {
11154 screenColumn += fm.getCharacterWidth(c);
11155 }
11156 if (screenColumn > maxScreenColumn) {
11157 break;
11158 }
11159 }
11160
11161 return [screenColumn, column];
11162 };
11163 };
11164
11165 this.destroy = function() {
11166 if (this.bgTokenizer) {
11167 this.bgTokenizer.setDocument(null);
11168 this.bgTokenizer = null;
11169 }
11170 this.$stopWorker();
11171 };
11172
11173 this.isFullWidth = isFullWidth;
11174 function isFullWidth(c) {
11175 if (c < 0x1100)
11176 return false;
11177 return c >= 0x1100 && c <= 0x115F ||
11178 c >= 0x11A3 && c <= 0x11A7 ||
11179 c >= 0x11FA && c <= 0x11FF ||
11180 c >= 0x2329 && c <= 0x232A ||
11181 c >= 0x2E80 && c <= 0x2E99 ||
11182 c >= 0x2E9B && c <= 0x2EF3 ||
11183 c >= 0x2F00 && c <= 0x2FD5 ||
11184 c >= 0x2FF0 && c <= 0x2FFB ||
11185 c >= 0x3000 && c <= 0x303E ||
11186 c >= 0x3041 && c <= 0x3096 ||
11187 c >= 0x3099 && c <= 0x30FF ||
11188 c >= 0x3105 && c <= 0x312D ||
11189 c >= 0x3131 && c <= 0x318E ||
11190 c >= 0x3190 && c <= 0x31BA ||
11191 c >= 0x31C0 && c <= 0x31E3 ||
11192 c >= 0x31F0 && c <= 0x321E ||
11193 c >= 0x3220 && c <= 0x3247 ||
11194 c >= 0x3250 && c <= 0x32FE ||
11195 c >= 0x3300 && c <= 0x4DBF ||
11196 c >= 0x4E00 && c <= 0xA48C ||
11197 c >= 0xA490 && c <= 0xA4C6 ||
11198 c >= 0xA960 && c <= 0xA97C ||
11199 c >= 0xAC00 && c <= 0xD7A3 ||
11200 c >= 0xD7B0 && c <= 0xD7C6 ||
11201 c >= 0xD7CB && c <= 0xD7FB ||
11202 c >= 0xF900 && c <= 0xFAFF ||
11203 c >= 0xFE10 && c <= 0xFE19 ||
11204 c >= 0xFE30 && c <= 0xFE52 ||
11205 c >= 0xFE54 && c <= 0xFE66 ||
11206 c >= 0xFE68 && c <= 0xFE6B ||
11207 c >= 0xFF01 && c <= 0xFF60 ||
11208 c >= 0xFFE0 && c <= 0xFFE6;
11209 }
11210
11211}).call(EditSession.prototype);
11212
11213acequire("./edit_session/folding").Folding.call(EditSession.prototype);
11214acequire("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
11215
11216
11217config.defineOptions(EditSession.prototype, "session", {
11218 wrap: {
11219 set: function(value) {
11220 if (!value || value == "off")
11221 value = false;
11222 else if (value == "free")
11223 value = true;
11224 else if (value == "printMargin")
11225 value = -1;
11226 else if (typeof value == "string")
11227 value = parseInt(value, 10) || false;
11228
11229 if (this.$wrap == value)
11230 return;
11231 this.$wrap = value;
11232 if (!value) {
11233 this.setUseWrapMode(false);
11234 } else {
11235 var col = typeof value == "number" ? value : null;
11236 this.setWrapLimitRange(col, col);
11237 this.setUseWrapMode(true);
11238 }
11239 },
11240 get: function() {
11241 if (this.getUseWrapMode()) {
11242 if (this.$wrap == -1)
11243 return "printMargin";
11244 if (!this.getWrapLimitRange().min)
11245 return "free";
11246 return this.$wrap;
11247 }
11248 return "off";
11249 },
11250 handlesSet: true
11251 },
11252 wrapMethod: {
11253 set: function(val) {
11254 val = val == "auto"
11255 ? this.$mode.type != "text"
11256 : val != "text";
11257 if (val != this.$wrapAsCode) {
11258 this.$wrapAsCode = val;
11259 if (this.$useWrapMode) {
11260 this.$modified = true;
11261 this.$resetRowCache(0);
11262 this.$updateWrapData(0, this.getLength() - 1);
11263 }
11264 }
11265 },
11266 initialValue: "auto"
11267 },
11268 indentedSoftWrap: { initialValue: true },
11269 firstLineNumber: {
11270 set: function() {this._signal("changeBreakpoint");},
11271 initialValue: 1
11272 },
11273 useWorker: {
11274 set: function(useWorker) {
11275 this.$useWorker = useWorker;
11276
11277 this.$stopWorker();
11278 if (useWorker)
11279 this.$startWorker();
11280 },
11281 initialValue: true
11282 },
11283 useSoftTabs: {initialValue: true},
11284 tabSize: {
11285 set: function(tabSize) {
11286 if (isNaN(tabSize) || this.$tabSize === tabSize) return;
11287
11288 this.$modified = true;
11289 this.$rowLengthCache = [];
11290 this.$tabSize = tabSize;
11291 this._signal("changeTabSize");
11292 },
11293 initialValue: 4,
11294 handlesSet: true
11295 },
11296 navigateWithinSoftTabs: {initialValue: false},
11297 overwrite: {
11298 set: function(val) {this._signal("changeOverwrite");},
11299 initialValue: false
11300 },
11301 newLineMode: {
11302 set: function(val) {this.doc.setNewLineMode(val);},
11303 get: function() {return this.doc.getNewLineMode();},
11304 handlesSet: true
11305 },
11306 mode: {
11307 set: function(val) { this.setMode(val); },
11308 get: function() { return this.$modeId; }
11309 }
11310});
11311
11312exports.EditSession = EditSession;
11313});
11314
11315ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(acequire, exports, module) {
11316
11317var lang = acequire("./lib/lang");
11318var oop = acequire("./lib/oop");
11319var Range = acequire("./range").Range;
11320
11321var Search = function() {
11322 this.$options = {};
11323};
11324
11325(function() {
11326 this.set = function(options) {
11327 oop.mixin(this.$options, options);
11328 return this;
11329 };
11330 this.getOptions = function() {
11331 return lang.copyObject(this.$options);
11332 };
11333 this.setOptions = function(options) {
11334 this.$options = options;
11335 };
11336 this.find = function(session) {
11337 var options = this.$options;
11338 var iterator = this.$matchIterator(session, options);
11339 if (!iterator)
11340 return false;
11341
11342 var firstRange = null;
11343 iterator.forEach(function(sr, sc, er, ec) {
11344 firstRange = new Range(sr, sc, er, ec);
11345 if (sc == ec && options.start && options.start.start
11346 && options.skipCurrent != false && firstRange.isEqual(options.start)
11347 ) {
11348 firstRange = null;
11349 return false;
11350 }
11351
11352 return true;
11353 });
11354
11355 return firstRange;
11356 };
11357 this.findAll = function(session) {
11358 var options = this.$options;
11359 if (!options.needle)
11360 return [];
11361 this.$assembleRegExp(options);
11362
11363 var range = options.range;
11364 var lines = range
11365 ? session.getLines(range.start.row, range.end.row)
11366 : session.doc.getAllLines();
11367
11368 var ranges = [];
11369 var re = options.re;
11370 if (options.$isMultiLine) {
11371 var len = re.length;
11372 var maxRow = lines.length - len;
11373 var prevRange;
11374 outer: for (var row = re.offset || 0; row <= maxRow; row++) {
11375 for (var j = 0; j < len; j++)
11376 if (lines[row + j].search(re[j]) == -1)
11377 continue outer;
11378
11379 var startLine = lines[row];
11380 var line = lines[row + len - 1];
11381 var startIndex = startLine.length - startLine.match(re[0])[0].length;
11382 var endIndex = line.match(re[len - 1])[0].length;
11383
11384 if (prevRange && prevRange.end.row === row &&
11385 prevRange.end.column > startIndex
11386 ) {
11387 continue;
11388 }
11389 ranges.push(prevRange = new Range(
11390 row, startIndex, row + len - 1, endIndex
11391 ));
11392 if (len > 2)
11393 row = row + len - 2;
11394 }
11395 } else {
11396 for (var i = 0; i < lines.length; i++) {
11397 var matches = lang.getMatchOffsets(lines[i], re);
11398 for (var j = 0; j < matches.length; j++) {
11399 var match = matches[j];
11400 ranges.push(new Range(i, match.offset, i, match.offset + match.length));
11401 }
11402 }
11403 }
11404
11405 if (range) {
11406 var startColumn = range.start.column;
11407 var endColumn = range.start.column;
11408 var i = 0, j = ranges.length - 1;
11409 while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)
11410 i++;
11411
11412 while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)
11413 j--;
11414
11415 ranges = ranges.slice(i, j + 1);
11416 for (i = 0, j = ranges.length; i < j; i++) {
11417 ranges[i].start.row += range.start.row;
11418 ranges[i].end.row += range.start.row;
11419 }
11420 }
11421
11422 return ranges;
11423 };
11424 this.replace = function(input, replacement) {
11425 var options = this.$options;
11426
11427 var re = this.$assembleRegExp(options);
11428 if (options.$isMultiLine)
11429 return replacement;
11430
11431 if (!re)
11432 return;
11433
11434 var match = re.exec(input);
11435 if (!match || match[0].length != input.length)
11436 return null;
11437
11438 replacement = input.replace(re, replacement);
11439 if (options.preserveCase) {
11440 replacement = replacement.split("");
11441 for (var i = Math.min(input.length, input.length); i--; ) {
11442 var ch = input[i];
11443 if (ch && ch.toLowerCase() != ch)
11444 replacement[i] = replacement[i].toUpperCase();
11445 else
11446 replacement[i] = replacement[i].toLowerCase();
11447 }
11448 replacement = replacement.join("");
11449 }
11450
11451 return replacement;
11452 };
11453
11454 this.$assembleRegExp = function(options, $disableFakeMultiline) {
11455 if (options.needle instanceof RegExp)
11456 return options.re = options.needle;
11457
11458 var needle = options.needle;
11459
11460 if (!options.needle)
11461 return options.re = false;
11462
11463 if (!options.regExp)
11464 needle = lang.escapeRegExp(needle);
11465
11466 if (options.wholeWord)
11467 needle = addWordBoundary(needle, options);
11468
11469 var modifier = options.caseSensitive ? "gm" : "gmi";
11470
11471 options.$isMultiLine = !$disableFakeMultiline && /[\n\r]/.test(needle);
11472 if (options.$isMultiLine)
11473 return options.re = this.$assembleMultilineRegExp(needle, modifier);
11474
11475 try {
11476 var re = new RegExp(needle, modifier);
11477 } catch(e) {
11478 re = false;
11479 }
11480 return options.re = re;
11481 };
11482
11483 this.$assembleMultilineRegExp = function(needle, modifier) {
11484 var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n");
11485 var re = [];
11486 for (var i = 0; i < parts.length; i++) try {
11487 re.push(new RegExp(parts[i], modifier));
11488 } catch(e) {
11489 return false;
11490 }
11491 return re;
11492 };
11493
11494 this.$matchIterator = function(session, options) {
11495 var re = this.$assembleRegExp(options);
11496 if (!re)
11497 return false;
11498 var backwards = options.backwards == true;
11499 var skipCurrent = options.skipCurrent != false;
11500
11501 var range = options.range;
11502 var start = options.start;
11503 if (!start)
11504 start = range ? range[backwards ? "end" : "start"] : session.selection.getRange();
11505
11506 if (start.start)
11507 start = start[skipCurrent != backwards ? "end" : "start"];
11508
11509 var firstRow = range ? range.start.row : 0;
11510 var lastRow = range ? range.end.row : session.getLength() - 1;
11511
11512 if (backwards) {
11513 var forEach = function(callback) {
11514 var row = start.row;
11515 if (forEachInLine(row, start.column, callback))
11516 return;
11517 for (row--; row >= firstRow; row--)
11518 if (forEachInLine(row, Number.MAX_VALUE, callback))
11519 return;
11520 if (options.wrap == false)
11521 return;
11522 for (row = lastRow, firstRow = start.row; row >= firstRow; row--)
11523 if (forEachInLine(row, Number.MAX_VALUE, callback))
11524 return;
11525 };
11526 }
11527 else {
11528 var forEach = function(callback) {
11529 var row = start.row;
11530 if (forEachInLine(row, start.column, callback))
11531 return;
11532 for (row = row + 1; row <= lastRow; row++)
11533 if (forEachInLine(row, 0, callback))
11534 return;
11535 if (options.wrap == false)
11536 return;
11537 for (row = firstRow, lastRow = start.row; row <= lastRow; row++)
11538 if (forEachInLine(row, 0, callback))
11539 return;
11540 };
11541 }
11542
11543 if (options.$isMultiLine) {
11544 var len = re.length;
11545 var forEachInLine = function(row, offset, callback) {
11546 var startRow = backwards ? row - len + 1 : row;
11547 if (startRow < 0) return;
11548 var line = session.getLine(startRow);
11549 var startIndex = line.search(re[0]);
11550 if (!backwards && startIndex < offset || startIndex === -1) return;
11551 for (var i = 1; i < len; i++) {
11552 line = session.getLine(startRow + i);
11553 if (line.search(re[i]) == -1)
11554 return;
11555 }
11556 var endIndex = line.match(re[len - 1])[0].length;
11557 if (backwards && endIndex > offset) return;
11558 if (callback(startRow, startIndex, startRow + len - 1, endIndex))
11559 return true;
11560 };
11561 }
11562 else if (backwards) {
11563 var forEachInLine = function(row, endIndex, callback) {
11564 var line = session.getLine(row);
11565 var matches = [];
11566 var m, last = 0;
11567 re.lastIndex = 0;
11568 while((m = re.exec(line))) {
11569 var length = m[0].length;
11570 last = m.index;
11571 if (!length) {
11572 if (last >= line.length) break;
11573 re.lastIndex = last += 1;
11574 }
11575 if (m.index + length > endIndex)
11576 break;
11577 matches.push(m.index, length);
11578 }
11579 for (var i = matches.length - 1; i >= 0; i -= 2) {
11580 var column = matches[i - 1];
11581 var length = matches[i];
11582 if (callback(row, column, row, column + length))
11583 return true;
11584 }
11585 };
11586 }
11587 else {
11588 var forEachInLine = function(row, startIndex, callback) {
11589 var line = session.getLine(row);
11590 var m;
11591 var last = startIndex;
11592 re.lastIndex = startIndex;
11593 while((m = re.exec(line))) {
11594 var length = m[0].length;
11595 last = m.index;
11596 if (callback(row, last, row,last + length))
11597 return true;
11598 if (!length) {
11599 re.lastIndex = last += 1;
11600 if (last >= line.length) return false;
11601 }
11602 }
11603 };
11604 }
11605 return {forEach: forEach};
11606 };
11607
11608}).call(Search.prototype);
11609
11610function addWordBoundary(needle, options) {
11611 function wordBoundary(c) {
11612 if (/\w/.test(c) || options.regExp) return "\\b";
11613 return "";
11614 }
11615 return wordBoundary(needle[0]) + needle
11616 + wordBoundary(needle[needle.length - 1]);
11617}
11618
11619exports.Search = Search;
11620});
11621
11622ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(acequire, exports, module) {
11623
11624var keyUtil = acequire("../lib/keys");
11625var useragent = acequire("../lib/useragent");
11626var KEY_MODS = keyUtil.KEY_MODS;
11627
11628function HashHandler(config, platform) {
11629 this.platform = platform || (useragent.isMac ? "mac" : "win");
11630 this.commands = {};
11631 this.commandKeyBinding = {};
11632 this.addCommands(config);
11633 this.$singleCommand = true;
11634}
11635
11636function MultiHashHandler(config, platform) {
11637 HashHandler.call(this, config, platform);
11638 this.$singleCommand = false;
11639}
11640
11641MultiHashHandler.prototype = HashHandler.prototype;
11642
11643(function() {
11644
11645
11646 this.addCommand = function(command) {
11647 if (this.commands[command.name])
11648 this.removeCommand(command);
11649
11650 this.commands[command.name] = command;
11651
11652 if (command.bindKey)
11653 this._buildKeyHash(command);
11654 };
11655
11656 this.removeCommand = function(command, keepCommand) {
11657 var name = command && (typeof command === 'string' ? command : command.name);
11658 command = this.commands[name];
11659 if (!keepCommand)
11660 delete this.commands[name];
11661 var ckb = this.commandKeyBinding;
11662 for (var keyId in ckb) {
11663 var cmdGroup = ckb[keyId];
11664 if (cmdGroup == command) {
11665 delete ckb[keyId];
11666 } else if (Array.isArray(cmdGroup)) {
11667 var i = cmdGroup.indexOf(command);
11668 if (i != -1) {
11669 cmdGroup.splice(i, 1);
11670 if (cmdGroup.length == 1)
11671 ckb[keyId] = cmdGroup[0];
11672 }
11673 }
11674 }
11675 };
11676
11677 this.bindKey = function(key, command, position) {
11678 if (typeof key == "object" && key) {
11679 if (position == undefined)
11680 position = key.position;
11681 key = key[this.platform];
11682 }
11683 if (!key)
11684 return;
11685 if (typeof command == "function")
11686 return this.addCommand({exec: command, bindKey: key, name: command.name || key});
11687
11688 key.split("|").forEach(function(keyPart) {
11689 var chain = "";
11690 if (keyPart.indexOf(" ") != -1) {
11691 var parts = keyPart.split(/\s+/);
11692 keyPart = parts.pop();
11693 parts.forEach(function(keyPart) {
11694 var binding = this.parseKeys(keyPart);
11695 var id = KEY_MODS[binding.hashId] + binding.key;
11696 chain += (chain ? " " : "") + id;
11697 this._addCommandToBinding(chain, "chainKeys");
11698 }, this);
11699 chain += " ";
11700 }
11701 var binding = this.parseKeys(keyPart);
11702 var id = KEY_MODS[binding.hashId] + binding.key;
11703 this._addCommandToBinding(chain + id, command, position);
11704 }, this);
11705 };
11706
11707 function getPosition(command) {
11708 return typeof command == "object" && command.bindKey
11709 && command.bindKey.position
11710 || (command.isDefault ? -100 : 0);
11711 }
11712 this._addCommandToBinding = function(keyId, command, position) {
11713 var ckb = this.commandKeyBinding, i;
11714 if (!command) {
11715 delete ckb[keyId];
11716 } else if (!ckb[keyId] || this.$singleCommand) {
11717 ckb[keyId] = command;
11718 } else {
11719 if (!Array.isArray(ckb[keyId])) {
11720 ckb[keyId] = [ckb[keyId]];
11721 } else if ((i = ckb[keyId].indexOf(command)) != -1) {
11722 ckb[keyId].splice(i, 1);
11723 }
11724
11725 if (typeof position != "number") {
11726 position = getPosition(command);
11727 }
11728
11729 var commands = ckb[keyId];
11730 for (i = 0; i < commands.length; i++) {
11731 var other = commands[i];
11732 var otherPos = getPosition(other);
11733 if (otherPos > position)
11734 break;
11735 }
11736 commands.splice(i, 0, command);
11737 }
11738 };
11739
11740 this.addCommands = function(commands) {
11741 commands && Object.keys(commands).forEach(function(name) {
11742 var command = commands[name];
11743 if (!command)
11744 return;
11745
11746 if (typeof command === "string")
11747 return this.bindKey(command, name);
11748
11749 if (typeof command === "function")
11750 command = { exec: command };
11751
11752 if (typeof command !== "object")
11753 return;
11754
11755 if (!command.name)
11756 command.name = name;
11757
11758 this.addCommand(command);
11759 }, this);
11760 };
11761
11762 this.removeCommands = function(commands) {
11763 Object.keys(commands).forEach(function(name) {
11764 this.removeCommand(commands[name]);
11765 }, this);
11766 };
11767
11768 this.bindKeys = function(keyList) {
11769 Object.keys(keyList).forEach(function(key) {
11770 this.bindKey(key, keyList[key]);
11771 }, this);
11772 };
11773
11774 this._buildKeyHash = function(command) {
11775 this.bindKey(command.bindKey, command);
11776 };
11777 this.parseKeys = function(keys) {
11778 var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x;});
11779 var key = parts.pop();
11780
11781 var keyCode = keyUtil[key];
11782 if (keyUtil.FUNCTION_KEYS[keyCode])
11783 key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();
11784 else if (!parts.length)
11785 return {key: key, hashId: -1};
11786 else if (parts.length == 1 && parts[0] == "shift")
11787 return {key: key.toUpperCase(), hashId: -1};
11788
11789 var hashId = 0;
11790 for (var i = parts.length; i--;) {
11791 var modifier = keyUtil.KEY_MODS[parts[i]];
11792 if (modifier == null) {
11793 if (typeof console != "undefined")
11794 console.error("invalid modifier " + parts[i] + " in " + keys);
11795 return false;
11796 }
11797 hashId |= modifier;
11798 }
11799 return {key: key, hashId: hashId};
11800 };
11801
11802 this.findKeyCommand = function findKeyCommand(hashId, keyString) {
11803 var key = KEY_MODS[hashId] + keyString;
11804 return this.commandKeyBinding[key];
11805 };
11806
11807 this.handleKeyboard = function(data, hashId, keyString, keyCode) {
11808 if (keyCode < 0) return;
11809 var key = KEY_MODS[hashId] + keyString;
11810 var command = this.commandKeyBinding[key];
11811 if (data.$keyChain) {
11812 data.$keyChain += " " + key;
11813 command = this.commandKeyBinding[data.$keyChain] || command;
11814 }
11815
11816 if (command) {
11817 if (command == "chainKeys" || command[command.length - 1] == "chainKeys") {
11818 data.$keyChain = data.$keyChain || key;
11819 return {command: "null"};
11820 }
11821 }
11822
11823 if (data.$keyChain) {
11824 if ((!hashId || hashId == 4) && keyString.length == 1)
11825 data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input
11826 else if (hashId == -1 || keyCode > 0)
11827 data.$keyChain = ""; // reset keyChain
11828 }
11829 return {command: command};
11830 };
11831
11832 this.getStatusText = function(editor, data) {
11833 return data.$keyChain || "";
11834 };
11835
11836}).call(HashHandler.prototype);
11837
11838exports.HashHandler = HashHandler;
11839exports.MultiHashHandler = MultiHashHandler;
11840});
11841
11842ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"], function(acequire, exports, module) {
11843
11844var oop = acequire("../lib/oop");
11845var MultiHashHandler = acequire("../keyboard/hash_handler").MultiHashHandler;
11846var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
11847
11848var CommandManager = function(platform, commands) {
11849 MultiHashHandler.call(this, commands, platform);
11850 this.byName = this.commands;
11851 this.setDefaultHandler("exec", function(e) {
11852 return e.command.exec(e.editor, e.args || {});
11853 });
11854};
11855
11856oop.inherits(CommandManager, MultiHashHandler);
11857
11858(function() {
11859
11860 oop.implement(this, EventEmitter);
11861
11862 this.exec = function(command, editor, args) {
11863 if (Array.isArray(command)) {
11864 for (var i = command.length; i--; ) {
11865 if (this.exec(command[i], editor, args)) return true;
11866 }
11867 return false;
11868 }
11869
11870 if (typeof command === "string")
11871 command = this.commands[command];
11872
11873 if (!command)
11874 return false;
11875
11876 if (editor && editor.$readOnly && !command.readOnly)
11877 return false;
11878
11879 if (command.isAvailable && !command.isAvailable(editor))
11880 return false;
11881
11882 var e = {editor: editor, command: command, args: args};
11883 e.returnValue = this._emit("exec", e);
11884 this._signal("afterExec", e);
11885
11886 return e.returnValue === false ? false : true;
11887 };
11888
11889 this.toggleRecording = function(editor) {
11890 if (this.$inReplay)
11891 return;
11892
11893 editor && editor._emit("changeStatus");
11894 if (this.recording) {
11895 this.macro.pop();
11896 this.removeEventListener("exec", this.$addCommandToMacro);
11897
11898 if (!this.macro.length)
11899 this.macro = this.oldMacro;
11900
11901 return this.recording = false;
11902 }
11903 if (!this.$addCommandToMacro) {
11904 this.$addCommandToMacro = function(e) {
11905 this.macro.push([e.command, e.args]);
11906 }.bind(this);
11907 }
11908
11909 this.oldMacro = this.macro;
11910 this.macro = [];
11911 this.on("exec", this.$addCommandToMacro);
11912 return this.recording = true;
11913 };
11914
11915 this.replay = function(editor) {
11916 if (this.$inReplay || !this.macro)
11917 return;
11918
11919 if (this.recording)
11920 return this.toggleRecording(editor);
11921
11922 try {
11923 this.$inReplay = true;
11924 this.macro.forEach(function(x) {
11925 if (typeof x == "string")
11926 this.exec(x, editor);
11927 else
11928 this.exec(x[0], editor, x[1]);
11929 }, this);
11930 } finally {
11931 this.$inReplay = false;
11932 }
11933 };
11934
11935 this.trimMacro = function(m) {
11936 return m.map(function(x){
11937 if (typeof x[0] != "string")
11938 x[0] = x[0].name;
11939 if (!x[1])
11940 x = x[0];
11941 return x;
11942 });
11943 };
11944
11945}).call(CommandManager.prototype);
11946
11947exports.CommandManager = CommandManager;
11948
11949});
11950
11951ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"], function(acequire, exports, module) {
11952
11953var lang = acequire("../lib/lang");
11954var config = acequire("../config");
11955var Range = acequire("../range").Range;
11956
11957function bindKey(win, mac) {
11958 return {win: win, mac: mac};
11959}
11960exports.commands = [{
11961 name: "showSettingsMenu",
11962 bindKey: bindKey("Ctrl-,", "Command-,"),
11963 exec: function(editor) {
11964 config.loadModule("ace/ext/settings_menu", function(module) {
11965 module.init(editor);
11966 editor.showSettingsMenu();
11967 });
11968 },
11969 readOnly: true
11970}, {
11971 name: "goToNextError",
11972 bindKey: bindKey("Alt-E", "F4"),
11973 exec: function(editor) {
11974 config.loadModule("ace/ext/error_marker", function(module) {
11975 module.showErrorMarker(editor, 1);
11976 });
11977 },
11978 scrollIntoView: "animate",
11979 readOnly: true
11980}, {
11981 name: "goToPreviousError",
11982 bindKey: bindKey("Alt-Shift-E", "Shift-F4"),
11983 exec: function(editor) {
11984 config.loadModule("ace/ext/error_marker", function(module) {
11985 module.showErrorMarker(editor, -1);
11986 });
11987 },
11988 scrollIntoView: "animate",
11989 readOnly: true
11990}, {
11991 name: "selectall",
11992 bindKey: bindKey("Ctrl-A", "Command-A"),
11993 exec: function(editor) { editor.selectAll(); },
11994 readOnly: true
11995}, {
11996 name: "centerselection",
11997 bindKey: bindKey(null, "Ctrl-L"),
11998 exec: function(editor) { editor.centerSelection(); },
11999 readOnly: true
12000}, {
12001 name: "gotoline",
12002 bindKey: bindKey("Ctrl-L", "Command-L"),
12003 exec: function(editor) {
12004 var line = parseInt(prompt("Enter line number:"), 10);
12005 if (!isNaN(line)) {
12006 editor.gotoLine(line);
12007 }
12008 },
12009 readOnly: true
12010}, {
12011 name: "fold",
12012 bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
12013 exec: function(editor) { editor.session.toggleFold(false); },
12014 multiSelectAction: "forEach",
12015 scrollIntoView: "center",
12016 readOnly: true
12017}, {
12018 name: "unfold",
12019 bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
12020 exec: function(editor) { editor.session.toggleFold(true); },
12021 multiSelectAction: "forEach",
12022 scrollIntoView: "center",
12023 readOnly: true
12024}, {
12025 name: "toggleFoldWidget",
12026 bindKey: bindKey("F2", "F2"),
12027 exec: function(editor) { editor.session.toggleFoldWidget(); },
12028 multiSelectAction: "forEach",
12029 scrollIntoView: "center",
12030 readOnly: true
12031}, {
12032 name: "toggleParentFoldWidget",
12033 bindKey: bindKey("Alt-F2", "Alt-F2"),
12034 exec: function(editor) { editor.session.toggleFoldWidget(true); },
12035 multiSelectAction: "forEach",
12036 scrollIntoView: "center",
12037 readOnly: true
12038}, {
12039 name: "foldall",
12040 bindKey: bindKey(null, "Ctrl-Command-Option-0"),
12041 exec: function(editor) { editor.session.foldAll(); },
12042 scrollIntoView: "center",
12043 readOnly: true
12044}, {
12045 name: "foldOther",
12046 bindKey: bindKey("Alt-0", "Command-Option-0"),
12047 exec: function(editor) {
12048 editor.session.foldAll();
12049 editor.session.unfold(editor.selection.getAllRanges());
12050 },
12051 scrollIntoView: "center",
12052 readOnly: true
12053}, {
12054 name: "unfoldall",
12055 bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
12056 exec: function(editor) { editor.session.unfold(); },
12057 scrollIntoView: "center",
12058 readOnly: true
12059}, {
12060 name: "findnext",
12061 bindKey: bindKey("Ctrl-K", "Command-G"),
12062 exec: function(editor) { editor.findNext(); },
12063 multiSelectAction: "forEach",
12064 scrollIntoView: "center",
12065 readOnly: true
12066}, {
12067 name: "findprevious",
12068 bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
12069 exec: function(editor) { editor.findPrevious(); },
12070 multiSelectAction: "forEach",
12071 scrollIntoView: "center",
12072 readOnly: true
12073}, {
12074 name: "selectOrFindNext",
12075 bindKey: bindKey("Alt-K", "Ctrl-G"),
12076 exec: function(editor) {
12077 if (editor.selection.isEmpty())
12078 editor.selection.selectWord();
12079 else
12080 editor.findNext();
12081 },
12082 readOnly: true
12083}, {
12084 name: "selectOrFindPrevious",
12085 bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"),
12086 exec: function(editor) {
12087 if (editor.selection.isEmpty())
12088 editor.selection.selectWord();
12089 else
12090 editor.findPrevious();
12091 },
12092 readOnly: true
12093}, {
12094 name: "find",
12095 bindKey: bindKey("Ctrl-F", "Command-F"),
12096 exec: function(editor) {
12097 config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor);});
12098 },
12099 readOnly: true
12100}, {
12101 name: "overwrite",
12102 bindKey: "Insert",
12103 exec: function(editor) { editor.toggleOverwrite(); },
12104 readOnly: true
12105}, {
12106 name: "selecttostart",
12107 bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Home|Command-Shift-Up"),
12108 exec: function(editor) { editor.getSelection().selectFileStart(); },
12109 multiSelectAction: "forEach",
12110 readOnly: true,
12111 scrollIntoView: "animate",
12112 aceCommandGroup: "fileJump"
12113}, {
12114 name: "gotostart",
12115 bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
12116 exec: function(editor) { editor.navigateFileStart(); },
12117 multiSelectAction: "forEach",
12118 readOnly: true,
12119 scrollIntoView: "animate",
12120 aceCommandGroup: "fileJump"
12121}, {
12122 name: "selectup",
12123 bindKey: bindKey("Shift-Up", "Shift-Up|Ctrl-Shift-P"),
12124 exec: function(editor) { editor.getSelection().selectUp(); },
12125 multiSelectAction: "forEach",
12126 scrollIntoView: "cursor",
12127 readOnly: true
12128}, {
12129 name: "golineup",
12130 bindKey: bindKey("Up", "Up|Ctrl-P"),
12131 exec: function(editor, args) { editor.navigateUp(args.times); },
12132 multiSelectAction: "forEach",
12133 scrollIntoView: "cursor",
12134 readOnly: true
12135}, {
12136 name: "selecttoend",
12137 bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-End|Command-Shift-Down"),
12138 exec: function(editor) { editor.getSelection().selectFileEnd(); },
12139 multiSelectAction: "forEach",
12140 readOnly: true,
12141 scrollIntoView: "animate",
12142 aceCommandGroup: "fileJump"
12143}, {
12144 name: "gotoend",
12145 bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
12146 exec: function(editor) { editor.navigateFileEnd(); },
12147 multiSelectAction: "forEach",
12148 readOnly: true,
12149 scrollIntoView: "animate",
12150 aceCommandGroup: "fileJump"
12151}, {
12152 name: "selectdown",
12153 bindKey: bindKey("Shift-Down", "Shift-Down|Ctrl-Shift-N"),
12154 exec: function(editor) { editor.getSelection().selectDown(); },
12155 multiSelectAction: "forEach",
12156 scrollIntoView: "cursor",
12157 readOnly: true
12158}, {
12159 name: "golinedown",
12160 bindKey: bindKey("Down", "Down|Ctrl-N"),
12161 exec: function(editor, args) { editor.navigateDown(args.times); },
12162 multiSelectAction: "forEach",
12163 scrollIntoView: "cursor",
12164 readOnly: true
12165}, {
12166 name: "selectwordleft",
12167 bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
12168 exec: function(editor) { editor.getSelection().selectWordLeft(); },
12169 multiSelectAction: "forEach",
12170 scrollIntoView: "cursor",
12171 readOnly: true
12172}, {
12173 name: "gotowordleft",
12174 bindKey: bindKey("Ctrl-Left", "Option-Left"),
12175 exec: function(editor) { editor.navigateWordLeft(); },
12176 multiSelectAction: "forEach",
12177 scrollIntoView: "cursor",
12178 readOnly: true
12179}, {
12180 name: "selecttolinestart",
12181 bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left|Ctrl-Shift-A"),
12182 exec: function(editor) { editor.getSelection().selectLineStart(); },
12183 multiSelectAction: "forEach",
12184 scrollIntoView: "cursor",
12185 readOnly: true
12186}, {
12187 name: "gotolinestart",
12188 bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
12189 exec: function(editor) { editor.navigateLineStart(); },
12190 multiSelectAction: "forEach",
12191 scrollIntoView: "cursor",
12192 readOnly: true
12193}, {
12194 name: "selectleft",
12195 bindKey: bindKey("Shift-Left", "Shift-Left|Ctrl-Shift-B"),
12196 exec: function(editor) { editor.getSelection().selectLeft(); },
12197 multiSelectAction: "forEach",
12198 scrollIntoView: "cursor",
12199 readOnly: true
12200}, {
12201 name: "gotoleft",
12202 bindKey: bindKey("Left", "Left|Ctrl-B"),
12203 exec: function(editor, args) { editor.navigateLeft(args.times); },
12204 multiSelectAction: "forEach",
12205 scrollIntoView: "cursor",
12206 readOnly: true
12207}, {
12208 name: "selectwordright",
12209 bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
12210 exec: function(editor) { editor.getSelection().selectWordRight(); },
12211 multiSelectAction: "forEach",
12212 scrollIntoView: "cursor",
12213 readOnly: true
12214}, {
12215 name: "gotowordright",
12216 bindKey: bindKey("Ctrl-Right", "Option-Right"),
12217 exec: function(editor) { editor.navigateWordRight(); },
12218 multiSelectAction: "forEach",
12219 scrollIntoView: "cursor",
12220 readOnly: true
12221}, {
12222 name: "selecttolineend",
12223 bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right|Shift-End|Ctrl-Shift-E"),
12224 exec: function(editor) { editor.getSelection().selectLineEnd(); },
12225 multiSelectAction: "forEach",
12226 scrollIntoView: "cursor",
12227 readOnly: true
12228}, {
12229 name: "gotolineend",
12230 bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
12231 exec: function(editor) { editor.navigateLineEnd(); },
12232 multiSelectAction: "forEach",
12233 scrollIntoView: "cursor",
12234 readOnly: true
12235}, {
12236 name: "selectright",
12237 bindKey: bindKey("Shift-Right", "Shift-Right"),
12238 exec: function(editor) { editor.getSelection().selectRight(); },
12239 multiSelectAction: "forEach",
12240 scrollIntoView: "cursor",
12241 readOnly: true
12242}, {
12243 name: "gotoright",
12244 bindKey: bindKey("Right", "Right|Ctrl-F"),
12245 exec: function(editor, args) { editor.navigateRight(args.times); },
12246 multiSelectAction: "forEach",
12247 scrollIntoView: "cursor",
12248 readOnly: true
12249}, {
12250 name: "selectpagedown",
12251 bindKey: "Shift-PageDown",
12252 exec: function(editor) { editor.selectPageDown(); },
12253 readOnly: true
12254}, {
12255 name: "pagedown",
12256 bindKey: bindKey(null, "Option-PageDown"),
12257 exec: function(editor) { editor.scrollPageDown(); },
12258 readOnly: true
12259}, {
12260 name: "gotopagedown",
12261 bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
12262 exec: function(editor) { editor.gotoPageDown(); },
12263 readOnly: true
12264}, {
12265 name: "selectpageup",
12266 bindKey: "Shift-PageUp",
12267 exec: function(editor) { editor.selectPageUp(); },
12268 readOnly: true
12269}, {
12270 name: "pageup",
12271 bindKey: bindKey(null, "Option-PageUp"),
12272 exec: function(editor) { editor.scrollPageUp(); },
12273 readOnly: true
12274}, {
12275 name: "gotopageup",
12276 bindKey: "PageUp",
12277 exec: function(editor) { editor.gotoPageUp(); },
12278 readOnly: true
12279}, {
12280 name: "scrollup",
12281 bindKey: bindKey("Ctrl-Up", null),
12282 exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
12283 readOnly: true
12284}, {
12285 name: "scrolldown",
12286 bindKey: bindKey("Ctrl-Down", null),
12287 exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
12288 readOnly: true
12289}, {
12290 name: "selectlinestart",
12291 bindKey: "Shift-Home",
12292 exec: function(editor) { editor.getSelection().selectLineStart(); },
12293 multiSelectAction: "forEach",
12294 scrollIntoView: "cursor",
12295 readOnly: true
12296}, {
12297 name: "selectlineend",
12298 bindKey: "Shift-End",
12299 exec: function(editor) { editor.getSelection().selectLineEnd(); },
12300 multiSelectAction: "forEach",
12301 scrollIntoView: "cursor",
12302 readOnly: true
12303}, {
12304 name: "togglerecording",
12305 bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
12306 exec: function(editor) { editor.commands.toggleRecording(editor); },
12307 readOnly: true
12308}, {
12309 name: "replaymacro",
12310 bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
12311 exec: function(editor) { editor.commands.replay(editor); },
12312 readOnly: true
12313}, {
12314 name: "jumptomatching",
12315 bindKey: bindKey("Ctrl-P", "Ctrl-P"),
12316 exec: function(editor) { editor.jumpToMatching(); },
12317 multiSelectAction: "forEach",
12318 scrollIntoView: "animate",
12319 readOnly: true
12320}, {
12321 name: "selecttomatching",
12322 bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
12323 exec: function(editor) { editor.jumpToMatching(true); },
12324 multiSelectAction: "forEach",
12325 scrollIntoView: "animate",
12326 readOnly: true
12327}, {
12328 name: "expandToMatching",
12329 bindKey: bindKey("Ctrl-Shift-M", "Ctrl-Shift-M"),
12330 exec: function(editor) { editor.jumpToMatching(true, true); },
12331 multiSelectAction: "forEach",
12332 scrollIntoView: "animate",
12333 readOnly: true
12334}, {
12335 name: "passKeysToBrowser",
12336 bindKey: bindKey(null, null),
12337 exec: function() {},
12338 passEvent: true,
12339 readOnly: true
12340}, {
12341 name: "copy",
12342 exec: function(editor) {
12343 },
12344 readOnly: true
12345},
12346{
12347 name: "cut",
12348 exec: function(editor) {
12349 var range = editor.getSelectionRange();
12350 editor._emit("cut", range);
12351
12352 if (!editor.selection.isEmpty()) {
12353 editor.session.remove(range);
12354 editor.clearSelection();
12355 }
12356 },
12357 scrollIntoView: "cursor",
12358 multiSelectAction: "forEach"
12359}, {
12360 name: "paste",
12361 exec: function(editor, args) {
12362 editor.$handlePaste(args);
12363 },
12364 scrollIntoView: "cursor"
12365}, {
12366 name: "removeline",
12367 bindKey: bindKey("Ctrl-D", "Command-D"),
12368 exec: function(editor) { editor.removeLines(); },
12369 scrollIntoView: "cursor",
12370 multiSelectAction: "forEachLine"
12371}, {
12372 name: "duplicateSelection",
12373 bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
12374 exec: function(editor) { editor.duplicateSelection(); },
12375 scrollIntoView: "cursor",
12376 multiSelectAction: "forEach"
12377}, {
12378 name: "sortlines",
12379 bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
12380 exec: function(editor) { editor.sortLines(); },
12381 scrollIntoView: "selection",
12382 multiSelectAction: "forEachLine"
12383}, {
12384 name: "togglecomment",
12385 bindKey: bindKey("Ctrl-/", "Command-/"),
12386 exec: function(editor) { editor.toggleCommentLines(); },
12387 multiSelectAction: "forEachLine",
12388 scrollIntoView: "selectionPart"
12389}, {
12390 name: "toggleBlockComment",
12391 bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
12392 exec: function(editor) { editor.toggleBlockComment(); },
12393 multiSelectAction: "forEach",
12394 scrollIntoView: "selectionPart"
12395}, {
12396 name: "modifyNumberUp",
12397 bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
12398 exec: function(editor) { editor.modifyNumber(1); },
12399 scrollIntoView: "cursor",
12400 multiSelectAction: "forEach"
12401}, {
12402 name: "modifyNumberDown",
12403 bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
12404 exec: function(editor) { editor.modifyNumber(-1); },
12405 scrollIntoView: "cursor",
12406 multiSelectAction: "forEach"
12407}, {
12408 name: "replace",
12409 bindKey: bindKey("Ctrl-H", "Command-Option-F"),
12410 exec: function(editor) {
12411 config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true);});
12412 }
12413}, {
12414 name: "undo",
12415 bindKey: bindKey("Ctrl-Z", "Command-Z"),
12416 exec: function(editor) { editor.undo(); }
12417}, {
12418 name: "redo",
12419 bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
12420 exec: function(editor) { editor.redo(); }
12421}, {
12422 name: "copylinesup",
12423 bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
12424 exec: function(editor) { editor.copyLinesUp(); },
12425 scrollIntoView: "cursor"
12426}, {
12427 name: "movelinesup",
12428 bindKey: bindKey("Alt-Up", "Option-Up"),
12429 exec: function(editor) { editor.moveLinesUp(); },
12430 scrollIntoView: "cursor"
12431}, {
12432 name: "copylinesdown",
12433 bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
12434 exec: function(editor) { editor.copyLinesDown(); },
12435 scrollIntoView: "cursor"
12436}, {
12437 name: "movelinesdown",
12438 bindKey: bindKey("Alt-Down", "Option-Down"),
12439 exec: function(editor) { editor.moveLinesDown(); },
12440 scrollIntoView: "cursor"
12441}, {
12442 name: "del",
12443 bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"),
12444 exec: function(editor) { editor.remove("right"); },
12445 multiSelectAction: "forEach",
12446 scrollIntoView: "cursor"
12447}, {
12448 name: "backspace",
12449 bindKey: bindKey(
12450 "Shift-Backspace|Backspace",
12451 "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"
12452 ),
12453 exec: function(editor) { editor.remove("left"); },
12454 multiSelectAction: "forEach",
12455 scrollIntoView: "cursor"
12456}, {
12457 name: "cut_or_delete",
12458 bindKey: bindKey("Shift-Delete", null),
12459 exec: function(editor) {
12460 if (editor.selection.isEmpty()) {
12461 editor.remove("left");
12462 } else {
12463 return false;
12464 }
12465 },
12466 multiSelectAction: "forEach",
12467 scrollIntoView: "cursor"
12468}, {
12469 name: "removetolinestart",
12470 bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
12471 exec: function(editor) { editor.removeToLineStart(); },
12472 multiSelectAction: "forEach",
12473 scrollIntoView: "cursor"
12474}, {
12475 name: "removetolineend",
12476 bindKey: bindKey("Alt-Delete", "Ctrl-K|Command-Delete"),
12477 exec: function(editor) { editor.removeToLineEnd(); },
12478 multiSelectAction: "forEach",
12479 scrollIntoView: "cursor"
12480}, {
12481 name: "removetolinestarthard",
12482 bindKey: bindKey("Ctrl-Shift-Backspace", null),
12483 exec: function(editor) {
12484 var range = editor.selection.getRange();
12485 range.start.column = 0;
12486 editor.session.remove(range);
12487 },
12488 multiSelectAction: "forEach",
12489 scrollIntoView: "cursor"
12490}, {
12491 name: "removetolineendhard",
12492 bindKey: bindKey("Ctrl-Shift-Delete", null),
12493 exec: function(editor) {
12494 var range = editor.selection.getRange();
12495 range.end.column = Number.MAX_VALUE;
12496 editor.session.remove(range);
12497 },
12498 multiSelectAction: "forEach",
12499 scrollIntoView: "cursor"
12500}, {
12501 name: "removewordleft",
12502 bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
12503 exec: function(editor) { editor.removeWordLeft(); },
12504 multiSelectAction: "forEach",
12505 scrollIntoView: "cursor"
12506}, {
12507 name: "removewordright",
12508 bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
12509 exec: function(editor) { editor.removeWordRight(); },
12510 multiSelectAction: "forEach",
12511 scrollIntoView: "cursor"
12512}, {
12513 name: "outdent",
12514 bindKey: bindKey("Shift-Tab", "Shift-Tab"),
12515 exec: function(editor) { editor.blockOutdent(); },
12516 multiSelectAction: "forEach",
12517 scrollIntoView: "selectionPart"
12518}, {
12519 name: "indent",
12520 bindKey: bindKey("Tab", "Tab"),
12521 exec: function(editor) { editor.indent(); },
12522 multiSelectAction: "forEach",
12523 scrollIntoView: "selectionPart"
12524}, {
12525 name: "blockoutdent",
12526 bindKey: bindKey("Ctrl-[", "Ctrl-["),
12527 exec: function(editor) { editor.blockOutdent(); },
12528 multiSelectAction: "forEachLine",
12529 scrollIntoView: "selectionPart"
12530}, {
12531 name: "blockindent",
12532 bindKey: bindKey("Ctrl-]", "Ctrl-]"),
12533 exec: function(editor) { editor.blockIndent(); },
12534 multiSelectAction: "forEachLine",
12535 scrollIntoView: "selectionPart"
12536}, {
12537 name: "insertstring",
12538 exec: function(editor, str) { editor.insert(str); },
12539 multiSelectAction: "forEach",
12540 scrollIntoView: "cursor"
12541}, {
12542 name: "inserttext",
12543 exec: function(editor, args) {
12544 editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
12545 },
12546 multiSelectAction: "forEach",
12547 scrollIntoView: "cursor"
12548}, {
12549 name: "splitline",
12550 bindKey: bindKey(null, "Ctrl-O"),
12551 exec: function(editor) { editor.splitLine(); },
12552 multiSelectAction: "forEach",
12553 scrollIntoView: "cursor"
12554}, {
12555 name: "transposeletters",
12556 bindKey: bindKey("Alt-Shift-X", "Ctrl-T"),
12557 exec: function(editor) { editor.transposeLetters(); },
12558 multiSelectAction: function(editor) {editor.transposeSelections(1); },
12559 scrollIntoView: "cursor"
12560}, {
12561 name: "touppercase",
12562 bindKey: bindKey("Ctrl-U", "Ctrl-U"),
12563 exec: function(editor) { editor.toUpperCase(); },
12564 multiSelectAction: "forEach",
12565 scrollIntoView: "cursor"
12566}, {
12567 name: "tolowercase",
12568 bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
12569 exec: function(editor) { editor.toLowerCase(); },
12570 multiSelectAction: "forEach",
12571 scrollIntoView: "cursor"
12572}, {
12573 name: "expandtoline",
12574 bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"),
12575 exec: function(editor) {
12576 var range = editor.selection.getRange();
12577
12578 range.start.column = range.end.column = 0;
12579 range.end.row++;
12580 editor.selection.setRange(range, false);
12581 },
12582 multiSelectAction: "forEach",
12583 scrollIntoView: "cursor",
12584 readOnly: true
12585}, {
12586 name: "joinlines",
12587 bindKey: bindKey(null, null),
12588 exec: function(editor) {
12589 var isBackwards = editor.selection.isBackwards();
12590 var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();
12591 var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();
12592 var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length;
12593 var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());
12594 var selectedCount = selectedText.replace(/\n\s*/, " ").length;
12595 var insertLine = editor.session.doc.getLine(selectionStart.row);
12596
12597 for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) {
12598 var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i)));
12599 if (curLine.length !== 0) {
12600 curLine = " " + curLine;
12601 }
12602 insertLine += curLine;
12603 }
12604
12605 if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {
12606 insertLine += editor.session.doc.getNewLineCharacter();
12607 }
12608
12609 editor.clearSelection();
12610 editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);
12611
12612 if (selectedCount > 0) {
12613 editor.selection.moveCursorTo(selectionStart.row, selectionStart.column);
12614 editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount);
12615 } else {
12616 firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol;
12617 editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol);
12618 }
12619 },
12620 multiSelectAction: "forEach",
12621 readOnly: true
12622}, {
12623 name: "invertSelection",
12624 bindKey: bindKey(null, null),
12625 exec: function(editor) {
12626 var endRow = editor.session.doc.getLength() - 1;
12627 var endCol = editor.session.doc.getLine(endRow).length;
12628 var ranges = editor.selection.rangeList.ranges;
12629 var newRanges = [];
12630 if (ranges.length < 1) {
12631 ranges = [editor.selection.getRange()];
12632 }
12633
12634 for (var i = 0; i < ranges.length; i++) {
12635 if (i == (ranges.length - 1)) {
12636 if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) {
12637 newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol));
12638 }
12639 }
12640
12641 if (i === 0) {
12642 if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) {
12643 newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column));
12644 }
12645 } else {
12646 newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column));
12647 }
12648 }
12649
12650 editor.exitMultiSelectMode();
12651 editor.clearSelection();
12652
12653 for(var i = 0; i < newRanges.length; i++) {
12654 editor.selection.addRange(newRanges[i], false);
12655 }
12656 },
12657 readOnly: true,
12658 scrollIntoView: "none"
12659}];
12660
12661});
12662
12663ace.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) {
12664
12665acequire("./lib/fixoldbrowsers");
12666
12667var oop = acequire("./lib/oop");
12668var dom = acequire("./lib/dom");
12669var lang = acequire("./lib/lang");
12670var useragent = acequire("./lib/useragent");
12671var TextInput = acequire("./keyboard/textinput").TextInput;
12672var MouseHandler = acequire("./mouse/mouse_handler").MouseHandler;
12673var FoldHandler = acequire("./mouse/fold_handler").FoldHandler;
12674var KeyBinding = acequire("./keyboard/keybinding").KeyBinding;
12675var EditSession = acequire("./edit_session").EditSession;
12676var Search = acequire("./search").Search;
12677var Range = acequire("./range").Range;
12678var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
12679var CommandManager = acequire("./commands/command_manager").CommandManager;
12680var defaultCommands = acequire("./commands/default_commands").commands;
12681var config = acequire("./config");
12682var TokenIterator = acequire("./token_iterator").TokenIterator;
12683var Editor = function(renderer, session) {
12684 var container = renderer.getContainerElement();
12685 this.container = container;
12686 this.renderer = renderer;
12687 this.id = "editor" + (++Editor.$uid);
12688
12689 this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
12690 if (typeof document == "object") {
12691 this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
12692 this.renderer.textarea = this.textInput.getElement();
12693 this.$mouseHandler = new MouseHandler(this);
12694 new FoldHandler(this);
12695 }
12696
12697 this.keyBinding = new KeyBinding(this);
12698
12699 this.$blockScrolling = 0;
12700 this.$search = new Search().set({
12701 wrap: true
12702 });
12703
12704 this.$historyTracker = this.$historyTracker.bind(this);
12705 this.commands.on("exec", this.$historyTracker);
12706
12707 this.$initOperationListeners();
12708
12709 this._$emitInputEvent = lang.delayedCall(function() {
12710 this._signal("input", {});
12711 if (this.session && this.session.bgTokenizer)
12712 this.session.bgTokenizer.scheduleStart();
12713 }.bind(this));
12714
12715 this.on("change", function(_, _self) {
12716 _self._$emitInputEvent.schedule(31);
12717 });
12718
12719 this.setSession(session || new EditSession(""));
12720 config.resetOptions(this);
12721 config._signal("editor", this);
12722};
12723
12724Editor.$uid = 0;
12725
12726(function(){
12727
12728 oop.implement(this, EventEmitter);
12729
12730 this.$initOperationListeners = function() {
12731
12732 this.selections = [];
12733 this.commands.on("exec", this.startOperation.bind(this), true);
12734 this.commands.on("afterExec", this.endOperation.bind(this), true);
12735
12736 this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
12737
12738 this.on("change", function() {
12739 this.curOp || this.startOperation();
12740 this.curOp.docChanged = true;
12741 }.bind(this), true);
12742
12743 this.on("changeSelection", function() {
12744 this.curOp || this.startOperation();
12745 this.curOp.selectionChanged = true;
12746 }.bind(this), true);
12747 };
12748
12749 this.curOp = null;
12750 this.prevOp = {};
12751 this.startOperation = function(commadEvent) {
12752 if (this.curOp) {
12753 if (!commadEvent || this.curOp.command)
12754 return;
12755 this.prevOp = this.curOp;
12756 }
12757 if (!commadEvent) {
12758 this.previousCommand = null;
12759 commadEvent = {};
12760 }
12761
12762 this.$opResetTimer.schedule();
12763 this.curOp = {
12764 command: commadEvent.command || {},
12765 args: commadEvent.args,
12766 scrollTop: this.renderer.scrollTop
12767 };
12768 if (this.curOp.command.name && this.curOp.command.scrollIntoView !== undefined)
12769 this.$blockScrolling++;
12770 };
12771
12772 this.endOperation = function(e) {
12773 if (this.curOp) {
12774 if (e && e.returnValue === false)
12775 return this.curOp = null;
12776 this._signal("beforeEndOperation");
12777 var command = this.curOp.command;
12778 if (command.name && this.$blockScrolling > 0)
12779 this.$blockScrolling--;
12780 var scrollIntoView = command && command.scrollIntoView;
12781 if (scrollIntoView) {
12782 switch (scrollIntoView) {
12783 case "center-animate":
12784 scrollIntoView = "animate";
12785 case "center":
12786 this.renderer.scrollCursorIntoView(null, 0.5);
12787 break;
12788 case "animate":
12789 case "cursor":
12790 this.renderer.scrollCursorIntoView();
12791 break;
12792 case "selectionPart":
12793 var range = this.selection.getRange();
12794 var config = this.renderer.layerConfig;
12795 if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
12796 this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
12797 }
12798 break;
12799 }
12800 if (scrollIntoView == "animate")
12801 this.renderer.animateScrolling(this.curOp.scrollTop);
12802 }
12803
12804 this.prevOp = this.curOp;
12805 this.curOp = null;
12806 }
12807 };
12808 this.$mergeableCommands = ["backspace", "del", "insertstring"];
12809 this.$historyTracker = function(e) {
12810 if (!this.$mergeUndoDeltas)
12811 return;
12812
12813 var prev = this.prevOp;
12814 var mergeableCommands = this.$mergeableCommands;
12815 var shouldMerge = prev.command && (e.command.name == prev.command.name);
12816 if (e.command.name == "insertstring") {
12817 var text = e.args;
12818 if (this.mergeNextCommand === undefined)
12819 this.mergeNextCommand = true;
12820
12821 shouldMerge = shouldMerge
12822 && this.mergeNextCommand // previous command allows to coalesce with
12823 && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
12824
12825 this.mergeNextCommand = true;
12826 } else {
12827 shouldMerge = shouldMerge
12828 && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
12829 }
12830
12831 if (
12832 this.$mergeUndoDeltas != "always"
12833 && Date.now() - this.sequenceStartTime > 2000
12834 ) {
12835 shouldMerge = false; // the sequence is too long
12836 }
12837
12838 if (shouldMerge)
12839 this.session.mergeUndoDeltas = true;
12840 else if (mergeableCommands.indexOf(e.command.name) !== -1)
12841 this.sequenceStartTime = Date.now();
12842 };
12843 this.setKeyboardHandler = function(keyboardHandler, cb) {
12844 if (keyboardHandler && typeof keyboardHandler === "string") {
12845 this.$keybindingId = keyboardHandler;
12846 var _self = this;
12847 config.loadModule(["keybinding", keyboardHandler], function(module) {
12848 if (_self.$keybindingId == keyboardHandler)
12849 _self.keyBinding.setKeyboardHandler(module && module.handler);
12850 cb && cb();
12851 });
12852 } else {
12853 this.$keybindingId = null;
12854 this.keyBinding.setKeyboardHandler(keyboardHandler);
12855 cb && cb();
12856 }
12857 };
12858 this.getKeyboardHandler = function() {
12859 return this.keyBinding.getKeyboardHandler();
12860 };
12861 this.setSession = function(session) {
12862 if (this.session == session)
12863 return;
12864 if (this.curOp) this.endOperation();
12865 this.curOp = {};
12866
12867 var oldSession = this.session;
12868 if (oldSession) {
12869 this.session.off("change", this.$onDocumentChange);
12870 this.session.off("changeMode", this.$onChangeMode);
12871 this.session.off("tokenizerUpdate", this.$onTokenizerUpdate);
12872 this.session.off("changeTabSize", this.$onChangeTabSize);
12873 this.session.off("changeWrapLimit", this.$onChangeWrapLimit);
12874 this.session.off("changeWrapMode", this.$onChangeWrapMode);
12875 this.session.off("changeFold", this.$onChangeFold);
12876 this.session.off("changeFrontMarker", this.$onChangeFrontMarker);
12877 this.session.off("changeBackMarker", this.$onChangeBackMarker);
12878 this.session.off("changeBreakpoint", this.$onChangeBreakpoint);
12879 this.session.off("changeAnnotation", this.$onChangeAnnotation);
12880 this.session.off("changeOverwrite", this.$onCursorChange);
12881 this.session.off("changeScrollTop", this.$onScrollTopChange);
12882 this.session.off("changeScrollLeft", this.$onScrollLeftChange);
12883
12884 var selection = this.session.getSelection();
12885 selection.off("changeCursor", this.$onCursorChange);
12886 selection.off("changeSelection", this.$onSelectionChange);
12887 }
12888
12889 this.session = session;
12890 if (session) {
12891 this.$onDocumentChange = this.onDocumentChange.bind(this);
12892 session.on("change", this.$onDocumentChange);
12893 this.renderer.setSession(session);
12894
12895 this.$onChangeMode = this.onChangeMode.bind(this);
12896 session.on("changeMode", this.$onChangeMode);
12897
12898 this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
12899 session.on("tokenizerUpdate", this.$onTokenizerUpdate);
12900
12901 this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
12902 session.on("changeTabSize", this.$onChangeTabSize);
12903
12904 this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
12905 session.on("changeWrapLimit", this.$onChangeWrapLimit);
12906
12907 this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
12908 session.on("changeWrapMode", this.$onChangeWrapMode);
12909
12910 this.$onChangeFold = this.onChangeFold.bind(this);
12911 session.on("changeFold", this.$onChangeFold);
12912
12913 this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
12914 this.session.on("changeFrontMarker", this.$onChangeFrontMarker);
12915
12916 this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
12917 this.session.on("changeBackMarker", this.$onChangeBackMarker);
12918
12919 this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
12920 this.session.on("changeBreakpoint", this.$onChangeBreakpoint);
12921
12922 this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
12923 this.session.on("changeAnnotation", this.$onChangeAnnotation);
12924
12925 this.$onCursorChange = this.onCursorChange.bind(this);
12926 this.session.on("changeOverwrite", this.$onCursorChange);
12927
12928 this.$onScrollTopChange = this.onScrollTopChange.bind(this);
12929 this.session.on("changeScrollTop", this.$onScrollTopChange);
12930
12931 this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
12932 this.session.on("changeScrollLeft", this.$onScrollLeftChange);
12933
12934 this.selection = session.getSelection();
12935 this.selection.on("changeCursor", this.$onCursorChange);
12936
12937 this.$onSelectionChange = this.onSelectionChange.bind(this);
12938 this.selection.on("changeSelection", this.$onSelectionChange);
12939
12940 this.onChangeMode();
12941
12942 this.$blockScrolling += 1;
12943 this.onCursorChange();
12944 this.$blockScrolling -= 1;
12945
12946 this.onScrollTopChange();
12947 this.onScrollLeftChange();
12948 this.onSelectionChange();
12949 this.onChangeFrontMarker();
12950 this.onChangeBackMarker();
12951 this.onChangeBreakpoint();
12952 this.onChangeAnnotation();
12953 this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
12954 this.renderer.updateFull();
12955 } else {
12956 this.selection = null;
12957 this.renderer.setSession(session);
12958 }
12959
12960 this._signal("changeSession", {
12961 session: session,
12962 oldSession: oldSession
12963 });
12964
12965 this.curOp = null;
12966
12967 oldSession && oldSession._signal("changeEditor", {oldEditor: this});
12968 session && session._signal("changeEditor", {editor: this});
12969
12970 if (session && session.bgTokenizer)
12971 session.bgTokenizer.scheduleStart();
12972 };
12973 this.getSession = function() {
12974 return this.session;
12975 };
12976 this.setValue = function(val, cursorPos) {
12977 this.session.doc.setValue(val);
12978
12979 if (!cursorPos)
12980 this.selectAll();
12981 else if (cursorPos == 1)
12982 this.navigateFileEnd();
12983 else if (cursorPos == -1)
12984 this.navigateFileStart();
12985
12986 return val;
12987 };
12988 this.getValue = function() {
12989 return this.session.getValue();
12990 };
12991 this.getSelection = function() {
12992 return this.selection;
12993 };
12994 this.resize = function(force) {
12995 this.renderer.onResize(force);
12996 };
12997 this.setTheme = function(theme, cb) {
12998 this.renderer.setTheme(theme, cb);
12999 };
13000 this.getTheme = function() {
13001 return this.renderer.getTheme();
13002 };
13003 this.setStyle = function(style) {
13004 this.renderer.setStyle(style);
13005 };
13006 this.unsetStyle = function(style) {
13007 this.renderer.unsetStyle(style);
13008 };
13009 this.getFontSize = function () {
13010 return this.getOption("fontSize") ||
13011 dom.computedStyle(this.container, "fontSize");
13012 };
13013 this.setFontSize = function(size) {
13014 this.setOption("fontSize", size);
13015 };
13016
13017 this.$highlightBrackets = function() {
13018 if (this.session.$bracketHighlight) {
13019 this.session.removeMarker(this.session.$bracketHighlight);
13020 this.session.$bracketHighlight = null;
13021 }
13022
13023 if (this.$highlightPending) {
13024 return;
13025 }
13026 var self = this;
13027 this.$highlightPending = true;
13028 setTimeout(function() {
13029 self.$highlightPending = false;
13030 var session = self.session;
13031 if (!session || !session.bgTokenizer) return;
13032 var pos = session.findMatchingBracket(self.getCursorPosition());
13033 if (pos) {
13034 var range = new Range(pos.row, pos.column, pos.row, pos.column + 1);
13035 } else if (session.$mode.getMatching) {
13036 var range = session.$mode.getMatching(self.session);
13037 }
13038 if (range)
13039 session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text");
13040 }, 50);
13041 };
13042 this.$highlightTags = function() {
13043 if (this.$highlightTagPending)
13044 return;
13045 var self = this;
13046 this.$highlightTagPending = true;
13047 setTimeout(function() {
13048 self.$highlightTagPending = false;
13049
13050 var session = self.session;
13051 if (!session || !session.bgTokenizer) return;
13052
13053 var pos = self.getCursorPosition();
13054 var iterator = new TokenIterator(self.session, pos.row, pos.column);
13055 var token = iterator.getCurrentToken();
13056
13057 if (!token || !/\b(?:tag-open|tag-name)/.test(token.type)) {
13058 session.removeMarker(session.$tagHighlight);
13059 session.$tagHighlight = null;
13060 return;
13061 }
13062
13063 if (token.type.indexOf("tag-open") != -1) {
13064 token = iterator.stepForward();
13065 if (!token)
13066 return;
13067 }
13068
13069 var tag = token.value;
13070 var depth = 0;
13071 var prevToken = iterator.stepBackward();
13072
13073 if (prevToken.value == '<'){
13074 do {
13075 prevToken = token;
13076 token = iterator.stepForward();
13077
13078 if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
13079 if (prevToken.value === '<'){
13080 depth++;
13081 } else if (prevToken.value === '</'){
13082 depth--;
13083 }
13084 }
13085
13086 } while (token && depth >= 0);
13087 } else {
13088 do {
13089 token = prevToken;
13090 prevToken = iterator.stepBackward();
13091
13092 if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
13093 if (prevToken.value === '<') {
13094 depth++;
13095 } else if (prevToken.value === '</') {
13096 depth--;
13097 }
13098 }
13099 } while (prevToken && depth <= 0);
13100 iterator.stepForward();
13101 }
13102
13103 if (!token) {
13104 session.removeMarker(session.$tagHighlight);
13105 session.$tagHighlight = null;
13106 return;
13107 }
13108
13109 var row = iterator.getCurrentTokenRow();
13110 var column = iterator.getCurrentTokenColumn();
13111 var range = new Range(row, column, row, column+token.value.length);
13112 var sbm = session.$backMarkers[session.$tagHighlight];
13113 if (session.$tagHighlight && sbm != undefined && range.compareRange(sbm.range) !== 0) {
13114 session.removeMarker(session.$tagHighlight);
13115 session.$tagHighlight = null;
13116 }
13117
13118 if (range && !session.$tagHighlight)
13119 session.$tagHighlight = session.addMarker(range, "ace_bracket", "text");
13120 }, 50);
13121 };
13122 this.focus = function() {
13123 var _self = this;
13124 setTimeout(function() {
13125 _self.textInput.focus();
13126 });
13127 this.textInput.focus();
13128 };
13129 this.isFocused = function() {
13130 return this.textInput.isFocused();
13131 };
13132 this.blur = function() {
13133 this.textInput.blur();
13134 };
13135 this.onFocus = function(e) {
13136 if (this.$isFocused)
13137 return;
13138 this.$isFocused = true;
13139 this.renderer.showCursor();
13140 this.renderer.visualizeFocus();
13141 this._emit("focus", e);
13142 };
13143 this.onBlur = function(e) {
13144 if (!this.$isFocused)
13145 return;
13146 this.$isFocused = false;
13147 this.renderer.hideCursor();
13148 this.renderer.visualizeBlur();
13149 this._emit("blur", e);
13150 };
13151
13152 this.$cursorChange = function() {
13153 this.renderer.updateCursor();
13154 };
13155 this.onDocumentChange = function(delta) {
13156 var wrap = this.session.$useWrapMode;
13157 var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);
13158 this.renderer.updateLines(delta.start.row, lastRow, wrap);
13159
13160 this._signal("change", delta);
13161 this.$cursorChange();
13162 this.$updateHighlightActiveLine();
13163 };
13164
13165 this.onTokenizerUpdate = function(e) {
13166 var rows = e.data;
13167 this.renderer.updateLines(rows.first, rows.last);
13168 };
13169
13170
13171 this.onScrollTopChange = function() {
13172 this.renderer.scrollToY(this.session.getScrollTop());
13173 };
13174
13175 this.onScrollLeftChange = function() {
13176 this.renderer.scrollToX(this.session.getScrollLeft());
13177 };
13178 this.onCursorChange = function() {
13179 this.$cursorChange();
13180
13181 if (!this.$blockScrolling) {
13182 config.warn("Automatically scrolling cursor into view after selection change",
13183 "this will be disabled in the next version",
13184 "set editor.$blockScrolling = Infinity to disable this message"
13185 );
13186 this.renderer.scrollCursorIntoView();
13187 }
13188
13189 this.$highlightBrackets();
13190 this.$highlightTags();
13191 this.$updateHighlightActiveLine();
13192 this._signal("changeSelection");
13193 };
13194
13195 this.$updateHighlightActiveLine = function() {
13196 var session = this.getSession();
13197
13198 var highlight;
13199 if (this.$highlightActiveLine) {
13200 if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
13201 highlight = this.getCursorPosition();
13202 if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
13203 highlight = false;
13204 }
13205
13206 if (session.$highlightLineMarker && !highlight) {
13207 session.removeMarker(session.$highlightLineMarker.id);
13208 session.$highlightLineMarker = null;
13209 } else if (!session.$highlightLineMarker && highlight) {
13210 var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
13211 range.id = session.addMarker(range, "ace_active-line", "screenLine");
13212 session.$highlightLineMarker = range;
13213 } else if (highlight) {
13214 session.$highlightLineMarker.start.row = highlight.row;
13215 session.$highlightLineMarker.end.row = highlight.row;
13216 session.$highlightLineMarker.start.column = highlight.column;
13217 session._signal("changeBackMarker");
13218 }
13219 };
13220
13221 this.onSelectionChange = function(e) {
13222 var session = this.session;
13223
13224 if (session.$selectionMarker) {
13225 session.removeMarker(session.$selectionMarker);
13226 }
13227 session.$selectionMarker = null;
13228
13229 if (!this.selection.isEmpty()) {
13230 var range = this.selection.getRange();
13231 var style = this.getSelectionStyle();
13232 session.$selectionMarker = session.addMarker(range, "ace_selection", style);
13233 } else {
13234 this.$updateHighlightActiveLine();
13235 }
13236
13237 var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
13238 this.session.highlight(re);
13239
13240 this._signal("changeSelection");
13241 };
13242
13243 this.$getSelectionHighLightRegexp = function() {
13244 var session = this.session;
13245
13246 var selection = this.getSelectionRange();
13247 if (selection.isEmpty() || selection.isMultiLine())
13248 return;
13249
13250 var startOuter = selection.start.column - 1;
13251 var endOuter = selection.end.column + 1;
13252 var line = session.getLine(selection.start.row);
13253 var lineCols = line.length;
13254 var needle = line.substring(Math.max(startOuter, 0),
13255 Math.min(endOuter, lineCols));
13256 if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
13257 (endOuter <= lineCols && /[\w\d]$/.test(needle)))
13258 return;
13259
13260 needle = line.substring(selection.start.column, selection.end.column);
13261 if (!/^[\w\d]+$/.test(needle))
13262 return;
13263
13264 var re = this.$search.$assembleRegExp({
13265 wholeWord: true,
13266 caseSensitive: true,
13267 needle: needle
13268 });
13269
13270 return re;
13271 };
13272
13273
13274 this.onChangeFrontMarker = function() {
13275 this.renderer.updateFrontMarkers();
13276 };
13277
13278 this.onChangeBackMarker = function() {
13279 this.renderer.updateBackMarkers();
13280 };
13281
13282
13283 this.onChangeBreakpoint = function() {
13284 this.renderer.updateBreakpoints();
13285 };
13286
13287 this.onChangeAnnotation = function() {
13288 this.renderer.setAnnotations(this.session.getAnnotations());
13289 };
13290
13291
13292 this.onChangeMode = function(e) {
13293 this.renderer.updateText();
13294 this._emit("changeMode", e);
13295 };
13296
13297
13298 this.onChangeWrapLimit = function() {
13299 this.renderer.updateFull();
13300 };
13301
13302 this.onChangeWrapMode = function() {
13303 this.renderer.onResize(true);
13304 };
13305
13306
13307 this.onChangeFold = function() {
13308 this.$updateHighlightActiveLine();
13309 this.renderer.updateFull();
13310 };
13311 this.getSelectedText = function() {
13312 return this.session.getTextRange(this.getSelectionRange());
13313 };
13314 this.getCopyText = function() {
13315 var text = this.getSelectedText();
13316 this._signal("copy", text);
13317 return text;
13318 };
13319 this.onCopy = function() {
13320 this.commands.exec("copy", this);
13321 };
13322 this.onCut = function() {
13323 this.commands.exec("cut", this);
13324 };
13325 this.onPaste = function(text, event) {
13326 var e = {text: text, event: event};
13327 this.commands.exec("paste", this, e);
13328 };
13329
13330 this.$handlePaste = function(e) {
13331 if (typeof e == "string")
13332 e = {text: e};
13333 this._signal("paste", e);
13334 var text = e.text;
13335 if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
13336 this.insert(text);
13337 } else {
13338 var lines = text.split(/\r\n|\r|\n/);
13339 var ranges = this.selection.rangeList.ranges;
13340
13341 if (lines.length > ranges.length || lines.length < 2 || !lines[1])
13342 return this.commands.exec("insertstring", this, text);
13343
13344 for (var i = ranges.length; i--;) {
13345 var range = ranges[i];
13346 if (!range.isEmpty())
13347 this.session.remove(range);
13348
13349 this.session.insert(range.start, lines[i]);
13350 }
13351 }
13352 };
13353
13354 this.execCommand = function(command, args) {
13355 return this.commands.exec(command, this, args);
13356 };
13357 this.insert = function(text, pasted) {
13358 var session = this.session;
13359 var mode = session.getMode();
13360 var cursor = this.getCursorPosition();
13361
13362 if (this.getBehavioursEnabled() && !pasted) {
13363 var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
13364 if (transform) {
13365 if (text !== transform.text) {
13366 this.session.mergeUndoDeltas = false;
13367 this.$mergeNextCommand = false;
13368 }
13369 text = transform.text;
13370
13371 }
13372 }
13373
13374 if (text == "\t")
13375 text = this.session.getTabString();
13376 if (!this.selection.isEmpty()) {
13377 var range = this.getSelectionRange();
13378 cursor = this.session.remove(range);
13379 this.clearSelection();
13380 }
13381 else if (this.session.getOverwrite() && text.indexOf("\n") == -1) {
13382 var range = new Range.fromPoints(cursor, cursor);
13383 range.end.column += text.length;
13384 this.session.remove(range);
13385 }
13386
13387 if (text == "\n" || text == "\r\n") {
13388 var line = session.getLine(cursor.row);
13389 if (cursor.column > line.search(/\S|$/)) {
13390 var d = line.substr(cursor.column).search(/\S|$/);
13391 session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
13392 }
13393 }
13394 this.clearSelection();
13395
13396 var start = cursor.column;
13397 var lineState = session.getState(cursor.row);
13398 var line = session.getLine(cursor.row);
13399 var shouldOutdent = mode.checkOutdent(lineState, line, text);
13400 session.insert(cursor, text);
13401
13402 if (transform && transform.selection) {
13403 if (transform.selection.length == 2) { // Transform relative to the current column
13404 this.selection.setSelectionRange(
13405 new Range(cursor.row, start + transform.selection[0],
13406 cursor.row, start + transform.selection[1]));
13407 } else { // Transform relative to the current row.
13408 this.selection.setSelectionRange(
13409 new Range(cursor.row + transform.selection[0],
13410 transform.selection[1],
13411 cursor.row + transform.selection[2],
13412 transform.selection[3]));
13413 }
13414 }
13415
13416 if (session.getDocument().isNewLine(text)) {
13417 var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
13418
13419 session.insert({row: cursor.row+1, column: 0}, lineIndent);
13420 }
13421 if (shouldOutdent)
13422 mode.autoOutdent(lineState, session, cursor.row);
13423 };
13424
13425 this.onTextInput = function(text) {
13426 this.keyBinding.onTextInput(text);
13427 };
13428
13429 this.onCommandKey = function(e, hashId, keyCode) {
13430 this.keyBinding.onCommandKey(e, hashId, keyCode);
13431 };
13432 this.setOverwrite = function(overwrite) {
13433 this.session.setOverwrite(overwrite);
13434 };
13435 this.getOverwrite = function() {
13436 return this.session.getOverwrite();
13437 };
13438 this.toggleOverwrite = function() {
13439 this.session.toggleOverwrite();
13440 };
13441 this.setScrollSpeed = function(speed) {
13442 this.setOption("scrollSpeed", speed);
13443 };
13444 this.getScrollSpeed = function() {
13445 return this.getOption("scrollSpeed");
13446 };
13447 this.setDragDelay = function(dragDelay) {
13448 this.setOption("dragDelay", dragDelay);
13449 };
13450 this.getDragDelay = function() {
13451 return this.getOption("dragDelay");
13452 };
13453 this.setSelectionStyle = function(val) {
13454 this.setOption("selectionStyle", val);
13455 };
13456 this.getSelectionStyle = function() {
13457 return this.getOption("selectionStyle");
13458 };
13459 this.setHighlightActiveLine = function(shouldHighlight) {
13460 this.setOption("highlightActiveLine", shouldHighlight);
13461 };
13462 this.getHighlightActiveLine = function() {
13463 return this.getOption("highlightActiveLine");
13464 };
13465 this.setHighlightGutterLine = function(shouldHighlight) {
13466 this.setOption("highlightGutterLine", shouldHighlight);
13467 };
13468
13469 this.getHighlightGutterLine = function() {
13470 return this.getOption("highlightGutterLine");
13471 };
13472 this.setHighlightSelectedWord = function(shouldHighlight) {
13473 this.setOption("highlightSelectedWord", shouldHighlight);
13474 };
13475 this.getHighlightSelectedWord = function() {
13476 return this.$highlightSelectedWord;
13477 };
13478
13479 this.setAnimatedScroll = function(shouldAnimate){
13480 this.renderer.setAnimatedScroll(shouldAnimate);
13481 };
13482
13483 this.getAnimatedScroll = function(){
13484 return this.renderer.getAnimatedScroll();
13485 };
13486 this.setShowInvisibles = function(showInvisibles) {
13487 this.renderer.setShowInvisibles(showInvisibles);
13488 };
13489 this.getShowInvisibles = function() {
13490 return this.renderer.getShowInvisibles();
13491 };
13492
13493 this.setDisplayIndentGuides = function(display) {
13494 this.renderer.setDisplayIndentGuides(display);
13495 };
13496
13497 this.getDisplayIndentGuides = function() {
13498 return this.renderer.getDisplayIndentGuides();
13499 };
13500 this.setShowPrintMargin = function(showPrintMargin) {
13501 this.renderer.setShowPrintMargin(showPrintMargin);
13502 };
13503 this.getShowPrintMargin = function() {
13504 return this.renderer.getShowPrintMargin();
13505 };
13506 this.setPrintMarginColumn = function(showPrintMargin) {
13507 this.renderer.setPrintMarginColumn(showPrintMargin);
13508 };
13509 this.getPrintMarginColumn = function() {
13510 return this.renderer.getPrintMarginColumn();
13511 };
13512 this.setReadOnly = function(readOnly) {
13513 this.setOption("readOnly", readOnly);
13514 };
13515 this.getReadOnly = function() {
13516 return this.getOption("readOnly");
13517 };
13518 this.setBehavioursEnabled = function (enabled) {
13519 this.setOption("behavioursEnabled", enabled);
13520 };
13521 this.getBehavioursEnabled = function () {
13522 return this.getOption("behavioursEnabled");
13523 };
13524 this.setWrapBehavioursEnabled = function (enabled) {
13525 this.setOption("wrapBehavioursEnabled", enabled);
13526 };
13527 this.getWrapBehavioursEnabled = function () {
13528 return this.getOption("wrapBehavioursEnabled");
13529 };
13530 this.setShowFoldWidgets = function(show) {
13531 this.setOption("showFoldWidgets", show);
13532
13533 };
13534 this.getShowFoldWidgets = function() {
13535 return this.getOption("showFoldWidgets");
13536 };
13537
13538 this.setFadeFoldWidgets = function(fade) {
13539 this.setOption("fadeFoldWidgets", fade);
13540 };
13541
13542 this.getFadeFoldWidgets = function() {
13543 return this.getOption("fadeFoldWidgets");
13544 };
13545 this.remove = function(dir) {
13546 if (this.selection.isEmpty()){
13547 if (dir == "left")
13548 this.selection.selectLeft();
13549 else
13550 this.selection.selectRight();
13551 }
13552
13553 var range = this.getSelectionRange();
13554 if (this.getBehavioursEnabled()) {
13555 var session = this.session;
13556 var state = session.getState(range.start.row);
13557 var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
13558
13559 if (range.end.column === 0) {
13560 var text = session.getTextRange(range);
13561 if (text[text.length - 1] == "\n") {
13562 var line = session.getLine(range.end.row);
13563 if (/^\s+$/.test(line)) {
13564 range.end.column = line.length;
13565 }
13566 }
13567 }
13568 if (new_range)
13569 range = new_range;
13570 }
13571
13572 this.session.remove(range);
13573 this.clearSelection();
13574 };
13575 this.removeWordRight = function() {
13576 if (this.selection.isEmpty())
13577 this.selection.selectWordRight();
13578
13579 this.session.remove(this.getSelectionRange());
13580 this.clearSelection();
13581 };
13582 this.removeWordLeft = function() {
13583 if (this.selection.isEmpty())
13584 this.selection.selectWordLeft();
13585
13586 this.session.remove(this.getSelectionRange());
13587 this.clearSelection();
13588 };
13589 this.removeToLineStart = function() {
13590 if (this.selection.isEmpty())
13591 this.selection.selectLineStart();
13592
13593 this.session.remove(this.getSelectionRange());
13594 this.clearSelection();
13595 };
13596 this.removeToLineEnd = function() {
13597 if (this.selection.isEmpty())
13598 this.selection.selectLineEnd();
13599
13600 var range = this.getSelectionRange();
13601 if (range.start.column == range.end.column && range.start.row == range.end.row) {
13602 range.end.column = 0;
13603 range.end.row++;
13604 }
13605
13606 this.session.remove(range);
13607 this.clearSelection();
13608 };
13609 this.splitLine = function() {
13610 if (!this.selection.isEmpty()) {
13611 this.session.remove(this.getSelectionRange());
13612 this.clearSelection();
13613 }
13614
13615 var cursor = this.getCursorPosition();
13616 this.insert("\n");
13617 this.moveCursorToPosition(cursor);
13618 };
13619 this.transposeLetters = function() {
13620 if (!this.selection.isEmpty()) {
13621 return;
13622 }
13623
13624 var cursor = this.getCursorPosition();
13625 var column = cursor.column;
13626 if (column === 0)
13627 return;
13628
13629 var line = this.session.getLine(cursor.row);
13630 var swap, range;
13631 if (column < line.length) {
13632 swap = line.charAt(column) + line.charAt(column-1);
13633 range = new Range(cursor.row, column-1, cursor.row, column+1);
13634 }
13635 else {
13636 swap = line.charAt(column-1) + line.charAt(column-2);
13637 range = new Range(cursor.row, column-2, cursor.row, column);
13638 }
13639 this.session.replace(range, swap);
13640 this.session.selection.moveToPosition(range.end);
13641 };
13642 this.toLowerCase = function() {
13643 var originalRange = this.getSelectionRange();
13644 if (this.selection.isEmpty()) {
13645 this.selection.selectWord();
13646 }
13647
13648 var range = this.getSelectionRange();
13649 var text = this.session.getTextRange(range);
13650 this.session.replace(range, text.toLowerCase());
13651 this.selection.setSelectionRange(originalRange);
13652 };
13653 this.toUpperCase = function() {
13654 var originalRange = this.getSelectionRange();
13655 if (this.selection.isEmpty()) {
13656 this.selection.selectWord();
13657 }
13658
13659 var range = this.getSelectionRange();
13660 var text = this.session.getTextRange(range);
13661 this.session.replace(range, text.toUpperCase());
13662 this.selection.setSelectionRange(originalRange);
13663 };
13664 this.indent = function() {
13665 var session = this.session;
13666 var range = this.getSelectionRange();
13667
13668 if (range.start.row < range.end.row) {
13669 var rows = this.$getSelectedRows();
13670 session.indentRows(rows.first, rows.last, "\t");
13671 return;
13672 } else if (range.start.column < range.end.column) {
13673 var text = session.getTextRange(range);
13674 if (!/^\s+$/.test(text)) {
13675 var rows = this.$getSelectedRows();
13676 session.indentRows(rows.first, rows.last, "\t");
13677 return;
13678 }
13679 }
13680
13681 var line = session.getLine(range.start.row);
13682 var position = range.start;
13683 var size = session.getTabSize();
13684 var column = session.documentToScreenColumn(position.row, position.column);
13685
13686 if (this.session.getUseSoftTabs()) {
13687 var count = (size - column % size);
13688 var indentString = lang.stringRepeat(" ", count);
13689 } else {
13690 var count = column % size;
13691 while (line[range.start.column - 1] == " " && count) {
13692 range.start.column--;
13693 count--;
13694 }
13695 this.selection.setSelectionRange(range);
13696 indentString = "\t";
13697 }
13698 return this.insert(indentString);
13699 };
13700 this.blockIndent = function() {
13701 var rows = this.$getSelectedRows();
13702 this.session.indentRows(rows.first, rows.last, "\t");
13703 };
13704 this.blockOutdent = function() {
13705 var selection = this.session.getSelection();
13706 this.session.outdentRows(selection.getRange());
13707 };
13708 this.sortLines = function() {
13709 var rows = this.$getSelectedRows();
13710 var session = this.session;
13711
13712 var lines = [];
13713 for (var i = rows.first; i <= rows.last; i++)
13714 lines.push(session.getLine(i));
13715
13716 lines.sort(function(a, b) {
13717 if (a.toLowerCase() < b.toLowerCase()) return -1;
13718 if (a.toLowerCase() > b.toLowerCase()) return 1;
13719 return 0;
13720 });
13721
13722 var deleteRange = new Range(0, 0, 0, 0);
13723 for (var i = rows.first; i <= rows.last; i++) {
13724 var line = session.getLine(i);
13725 deleteRange.start.row = i;
13726 deleteRange.end.row = i;
13727 deleteRange.end.column = line.length;
13728 session.replace(deleteRange, lines[i-rows.first]);
13729 }
13730 };
13731 this.toggleCommentLines = function() {
13732 var state = this.session.getState(this.getCursorPosition().row);
13733 var rows = this.$getSelectedRows();
13734 this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
13735 };
13736
13737 this.toggleBlockComment = function() {
13738 var cursor = this.getCursorPosition();
13739 var state = this.session.getState(cursor.row);
13740 var range = this.getSelectionRange();
13741 this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
13742 };
13743 this.getNumberAt = function(row, column) {
13744 var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
13745 _numberRx.lastIndex = 0;
13746
13747 var s = this.session.getLine(row);
13748 while (_numberRx.lastIndex < column) {
13749 var m = _numberRx.exec(s);
13750 if(m.index <= column && m.index+m[0].length >= column){
13751 var number = {
13752 value: m[0],
13753 start: m.index,
13754 end: m.index+m[0].length
13755 };
13756 return number;
13757 }
13758 }
13759 return null;
13760 };
13761 this.modifyNumber = function(amount) {
13762 var row = this.selection.getCursor().row;
13763 var column = this.selection.getCursor().column;
13764 var charRange = new Range(row, column-1, row, column);
13765
13766 var c = this.session.getTextRange(charRange);
13767 if (!isNaN(parseFloat(c)) && isFinite(c)) {
13768 var nr = this.getNumberAt(row, column);
13769 if (nr) {
13770 var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
13771 var decimals = nr.start + nr.value.length - fp;
13772
13773 var t = parseFloat(nr.value);
13774 t *= Math.pow(10, decimals);
13775
13776
13777 if(fp !== nr.end && column < fp){
13778 amount *= Math.pow(10, nr.end - column - 1);
13779 } else {
13780 amount *= Math.pow(10, nr.end - column);
13781 }
13782
13783 t += amount;
13784 t /= Math.pow(10, decimals);
13785 var nnr = t.toFixed(decimals);
13786 var replaceRange = new Range(row, nr.start, row, nr.end);
13787 this.session.replace(replaceRange, nnr);
13788 this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
13789
13790 }
13791 }
13792 };
13793 this.removeLines = function() {
13794 var rows = this.$getSelectedRows();
13795 this.session.removeFullLines(rows.first, rows.last);
13796 this.clearSelection();
13797 };
13798
13799 this.duplicateSelection = function() {
13800 var sel = this.selection;
13801 var doc = this.session;
13802 var range = sel.getRange();
13803 var reverse = sel.isBackwards();
13804 if (range.isEmpty()) {
13805 var row = range.start.row;
13806 doc.duplicateLines(row, row);
13807 } else {
13808 var point = reverse ? range.start : range.end;
13809 var endPoint = doc.insert(point, doc.getTextRange(range), false);
13810 range.start = point;
13811 range.end = endPoint;
13812
13813 sel.setSelectionRange(range, reverse);
13814 }
13815 };
13816 this.moveLinesDown = function() {
13817 this.$moveLines(1, false);
13818 };
13819 this.moveLinesUp = function() {
13820 this.$moveLines(-1, false);
13821 };
13822 this.moveText = function(range, toPosition, copy) {
13823 return this.session.moveText(range, toPosition, copy);
13824 };
13825 this.copyLinesUp = function() {
13826 this.$moveLines(-1, true);
13827 };
13828 this.copyLinesDown = function() {
13829 this.$moveLines(1, true);
13830 };
13831 this.$moveLines = function(dir, copy) {
13832 var rows, moved;
13833 var selection = this.selection;
13834 if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
13835 var range = selection.toOrientedRange();
13836 rows = this.$getSelectedRows(range);
13837 moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
13838 if (copy && dir == -1) moved = 0;
13839 range.moveBy(moved, 0);
13840 selection.fromOrientedRange(range);
13841 } else {
13842 var ranges = selection.rangeList.ranges;
13843 selection.rangeList.detach(this.session);
13844 this.inVirtualSelectionMode = true;
13845
13846 var diff = 0;
13847 var totalDiff = 0;
13848 var l = ranges.length;
13849 for (var i = 0; i < l; i++) {
13850 var rangeIndex = i;
13851 ranges[i].moveBy(diff, 0);
13852 rows = this.$getSelectedRows(ranges[i]);
13853 var first = rows.first;
13854 var last = rows.last;
13855 while (++i < l) {
13856 if (totalDiff) ranges[i].moveBy(totalDiff, 0);
13857 var subRows = this.$getSelectedRows(ranges[i]);
13858 if (copy && subRows.first != last)
13859 break;
13860 else if (!copy && subRows.first > last + 1)
13861 break;
13862 last = subRows.last;
13863 }
13864 i--;
13865 diff = this.session.$moveLines(first, last, copy ? 0 : dir);
13866 if (copy && dir == -1) rangeIndex = i + 1;
13867 while (rangeIndex <= i) {
13868 ranges[rangeIndex].moveBy(diff, 0);
13869 rangeIndex++;
13870 }
13871 if (!copy) diff = 0;
13872 totalDiff += diff;
13873 }
13874
13875 selection.fromOrientedRange(selection.ranges[0]);
13876 selection.rangeList.attach(this.session);
13877 this.inVirtualSelectionMode = false;
13878 }
13879 };
13880 this.$getSelectedRows = function(range) {
13881 range = (range || this.getSelectionRange()).collapseRows();
13882
13883 return {
13884 first: this.session.getRowFoldStart(range.start.row),
13885 last: this.session.getRowFoldEnd(range.end.row)
13886 };
13887 };
13888
13889 this.onCompositionStart = function(text) {
13890 this.renderer.showComposition(this.getCursorPosition());
13891 };
13892
13893 this.onCompositionUpdate = function(text) {
13894 this.renderer.setCompositionText(text);
13895 };
13896
13897 this.onCompositionEnd = function() {
13898 this.renderer.hideComposition();
13899 };
13900 this.getFirstVisibleRow = function() {
13901 return this.renderer.getFirstVisibleRow();
13902 };
13903 this.getLastVisibleRow = function() {
13904 return this.renderer.getLastVisibleRow();
13905 };
13906 this.isRowVisible = function(row) {
13907 return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
13908 };
13909 this.isRowFullyVisible = function(row) {
13910 return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
13911 };
13912 this.$getVisibleRowCount = function() {
13913 return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
13914 };
13915
13916 this.$moveByPage = function(dir, select) {
13917 var renderer = this.renderer;
13918 var config = this.renderer.layerConfig;
13919 var rows = dir * Math.floor(config.height / config.lineHeight);
13920
13921 this.$blockScrolling++;
13922 if (select === true) {
13923 this.selection.$moveSelection(function(){
13924 this.moveCursorBy(rows, 0);
13925 });
13926 } else if (select === false) {
13927 this.selection.moveCursorBy(rows, 0);
13928 this.selection.clearSelection();
13929 }
13930 this.$blockScrolling--;
13931
13932 var scrollTop = renderer.scrollTop;
13933
13934 renderer.scrollBy(0, rows * config.lineHeight);
13935 if (select != null)
13936 renderer.scrollCursorIntoView(null, 0.5);
13937
13938 renderer.animateScrolling(scrollTop);
13939 };
13940 this.selectPageDown = function() {
13941 this.$moveByPage(1, true);
13942 };
13943 this.selectPageUp = function() {
13944 this.$moveByPage(-1, true);
13945 };
13946 this.gotoPageDown = function() {
13947 this.$moveByPage(1, false);
13948 };
13949 this.gotoPageUp = function() {
13950 this.$moveByPage(-1, false);
13951 };
13952 this.scrollPageDown = function() {
13953 this.$moveByPage(1);
13954 };
13955 this.scrollPageUp = function() {
13956 this.$moveByPage(-1);
13957 };
13958 this.scrollToRow = function(row) {
13959 this.renderer.scrollToRow(row);
13960 };
13961 this.scrollToLine = function(line, center, animate, callback) {
13962 this.renderer.scrollToLine(line, center, animate, callback);
13963 };
13964 this.centerSelection = function() {
13965 var range = this.getSelectionRange();
13966 var pos = {
13967 row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
13968 column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
13969 };
13970 this.renderer.alignCursor(pos, 0.5);
13971 };
13972 this.getCursorPosition = function() {
13973 return this.selection.getCursor();
13974 };
13975 this.getCursorPositionScreen = function() {
13976 return this.session.documentToScreenPosition(this.getCursorPosition());
13977 };
13978 this.getSelectionRange = function() {
13979 return this.selection.getRange();
13980 };
13981 this.selectAll = function() {
13982 this.$blockScrolling += 1;
13983 this.selection.selectAll();
13984 this.$blockScrolling -= 1;
13985 };
13986 this.clearSelection = function() {
13987 this.selection.clearSelection();
13988 };
13989 this.moveCursorTo = function(row, column) {
13990 this.selection.moveCursorTo(row, column);
13991 };
13992 this.moveCursorToPosition = function(pos) {
13993 this.selection.moveCursorToPosition(pos);
13994 };
13995 this.jumpToMatching = function(select, expand) {
13996 var cursor = this.getCursorPosition();
13997 var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
13998 var prevToken = iterator.getCurrentToken();
13999 var token = prevToken || iterator.stepForward();
14000
14001 if (!token) return;
14002 var matchType;
14003 var found = false;
14004 var depth = {};
14005 var i = cursor.column - token.start;
14006 var bracketType;
14007 var brackets = {
14008 ")": "(",
14009 "(": "(",
14010 "]": "[",
14011 "[": "[",
14012 "{": "{",
14013 "}": "{"
14014 };
14015
14016 do {
14017 if (token.value.match(/[{}()\[\]]/g)) {
14018 for (; i < token.value.length && !found; i++) {
14019 if (!brackets[token.value[i]]) {
14020 continue;
14021 }
14022
14023 bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
14024
14025 if (isNaN(depth[bracketType])) {
14026 depth[bracketType] = 0;
14027 }
14028
14029 switch (token.value[i]) {
14030 case '(':
14031 case '[':
14032 case '{':
14033 depth[bracketType]++;
14034 break;
14035 case ')':
14036 case ']':
14037 case '}':
14038 depth[bracketType]--;
14039
14040 if (depth[bracketType] === -1) {
14041 matchType = 'bracket';
14042 found = true;
14043 }
14044 break;
14045 }
14046 }
14047 }
14048 else if (token && token.type.indexOf('tag-name') !== -1) {
14049 if (isNaN(depth[token.value])) {
14050 depth[token.value] = 0;
14051 }
14052
14053 if (prevToken.value === '<') {
14054 depth[token.value]++;
14055 }
14056 else if (prevToken.value === '</') {
14057 depth[token.value]--;
14058 }
14059
14060 if (depth[token.value] === -1) {
14061 matchType = 'tag';
14062 found = true;
14063 }
14064 }
14065
14066 if (!found) {
14067 prevToken = token;
14068 token = iterator.stepForward();
14069 i = 0;
14070 }
14071 } while (token && !found);
14072 if (!matchType)
14073 return;
14074
14075 var range, pos;
14076 if (matchType === 'bracket') {
14077 range = this.session.getBracketRange(cursor);
14078 if (!range) {
14079 range = new Range(
14080 iterator.getCurrentTokenRow(),
14081 iterator.getCurrentTokenColumn() + i - 1,
14082 iterator.getCurrentTokenRow(),
14083 iterator.getCurrentTokenColumn() + i - 1
14084 );
14085 pos = range.start;
14086 if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)
14087 range = this.session.getBracketRange(pos);
14088 }
14089 }
14090 else if (matchType === 'tag') {
14091 if (token && token.type.indexOf('tag-name') !== -1)
14092 var tag = token.value;
14093 else
14094 return;
14095
14096 range = new Range(
14097 iterator.getCurrentTokenRow(),
14098 iterator.getCurrentTokenColumn() - 2,
14099 iterator.getCurrentTokenRow(),
14100 iterator.getCurrentTokenColumn() - 2
14101 );
14102 if (range.compare(cursor.row, cursor.column) === 0) {
14103 found = false;
14104 do {
14105 token = prevToken;
14106 prevToken = iterator.stepBackward();
14107
14108 if (prevToken) {
14109 if (prevToken.type.indexOf('tag-close') !== -1) {
14110 range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);
14111 }
14112
14113 if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
14114 if (prevToken.value === '<') {
14115 depth[tag]++;
14116 }
14117 else if (prevToken.value === '</') {
14118 depth[tag]--;
14119 }
14120
14121 if (depth[tag] === 0)
14122 found = true;
14123 }
14124 }
14125 } while (prevToken && !found);
14126 }
14127 if (token && token.type.indexOf('tag-name')) {
14128 pos = range.start;
14129 if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
14130 pos = range.end;
14131 }
14132 }
14133
14134 pos = range && range.cursor || pos;
14135 if (pos) {
14136 if (select) {
14137 if (range && expand) {
14138 this.selection.setRange(range);
14139 } else if (range && range.isEqual(this.getSelectionRange())) {
14140 this.clearSelection();
14141 } else {
14142 this.selection.selectTo(pos.row, pos.column);
14143 }
14144 } else {
14145 this.selection.moveTo(pos.row, pos.column);
14146 }
14147 }
14148 };
14149 this.gotoLine = function(lineNumber, column, animate) {
14150 this.selection.clearSelection();
14151 this.session.unfold({row: lineNumber - 1, column: column || 0});
14152
14153 this.$blockScrolling += 1;
14154 this.exitMultiSelectMode && this.exitMultiSelectMode();
14155 this.moveCursorTo(lineNumber - 1, column || 0);
14156 this.$blockScrolling -= 1;
14157
14158 if (!this.isRowFullyVisible(lineNumber - 1))
14159 this.scrollToLine(lineNumber - 1, true, animate);
14160 };
14161 this.navigateTo = function(row, column) {
14162 this.selection.moveTo(row, column);
14163 };
14164 this.navigateUp = function(times) {
14165 if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
14166 var selectionStart = this.selection.anchor.getPosition();
14167 return this.moveCursorToPosition(selectionStart);
14168 }
14169 this.selection.clearSelection();
14170 this.selection.moveCursorBy(-times || -1, 0);
14171 };
14172 this.navigateDown = function(times) {
14173 if (this.selection.isMultiLine() && this.selection.isBackwards()) {
14174 var selectionEnd = this.selection.anchor.getPosition();
14175 return this.moveCursorToPosition(selectionEnd);
14176 }
14177 this.selection.clearSelection();
14178 this.selection.moveCursorBy(times || 1, 0);
14179 };
14180 this.navigateLeft = function(times) {
14181 if (!this.selection.isEmpty()) {
14182 var selectionStart = this.getSelectionRange().start;
14183 this.moveCursorToPosition(selectionStart);
14184 }
14185 else {
14186 times = times || 1;
14187 while (times--) {
14188 this.selection.moveCursorLeft();
14189 }
14190 }
14191 this.clearSelection();
14192 };
14193 this.navigateRight = function(times) {
14194 if (!this.selection.isEmpty()) {
14195 var selectionEnd = this.getSelectionRange().end;
14196 this.moveCursorToPosition(selectionEnd);
14197 }
14198 else {
14199 times = times || 1;
14200 while (times--) {
14201 this.selection.moveCursorRight();
14202 }
14203 }
14204 this.clearSelection();
14205 };
14206 this.navigateLineStart = function() {
14207 this.selection.moveCursorLineStart();
14208 this.clearSelection();
14209 };
14210 this.navigateLineEnd = function() {
14211 this.selection.moveCursorLineEnd();
14212 this.clearSelection();
14213 };
14214 this.navigateFileEnd = function() {
14215 this.selection.moveCursorFileEnd();
14216 this.clearSelection();
14217 };
14218 this.navigateFileStart = function() {
14219 this.selection.moveCursorFileStart();
14220 this.clearSelection();
14221 };
14222 this.navigateWordRight = function() {
14223 this.selection.moveCursorWordRight();
14224 this.clearSelection();
14225 };
14226 this.navigateWordLeft = function() {
14227 this.selection.moveCursorWordLeft();
14228 this.clearSelection();
14229 };
14230 this.replace = function(replacement, options) {
14231 if (options)
14232 this.$search.set(options);
14233
14234 var range = this.$search.find(this.session);
14235 var replaced = 0;
14236 if (!range)
14237 return replaced;
14238
14239 if (this.$tryReplace(range, replacement)) {
14240 replaced = 1;
14241 }
14242 if (range !== null) {
14243 this.selection.setSelectionRange(range);
14244 this.renderer.scrollSelectionIntoView(range.start, range.end);
14245 }
14246
14247 return replaced;
14248 };
14249 this.replaceAll = function(replacement, options) {
14250 if (options) {
14251 this.$search.set(options);
14252 }
14253
14254 var ranges = this.$search.findAll(this.session);
14255 var replaced = 0;
14256 if (!ranges.length)
14257 return replaced;
14258
14259 this.$blockScrolling += 1;
14260
14261 var selection = this.getSelectionRange();
14262 this.selection.moveTo(0, 0);
14263
14264 for (var i = ranges.length - 1; i >= 0; --i) {
14265 if(this.$tryReplace(ranges[i], replacement)) {
14266 replaced++;
14267 }
14268 }
14269
14270 this.selection.setSelectionRange(selection);
14271 this.$blockScrolling -= 1;
14272
14273 return replaced;
14274 };
14275
14276 this.$tryReplace = function(range, replacement) {
14277 var input = this.session.getTextRange(range);
14278 replacement = this.$search.replace(input, replacement);
14279 if (replacement !== null) {
14280 range.end = this.session.replace(range, replacement);
14281 return range;
14282 } else {
14283 return null;
14284 }
14285 };
14286 this.getLastSearchOptions = function() {
14287 return this.$search.getOptions();
14288 };
14289 this.find = function(needle, options, animate) {
14290 if (!options)
14291 options = {};
14292
14293 if (typeof needle == "string" || needle instanceof RegExp)
14294 options.needle = needle;
14295 else if (typeof needle == "object")
14296 oop.mixin(options, needle);
14297
14298 var range = this.selection.getRange();
14299 if (options.needle == null) {
14300 needle = this.session.getTextRange(range)
14301 || this.$search.$options.needle;
14302 if (!needle) {
14303 range = this.session.getWordRange(range.start.row, range.start.column);
14304 needle = this.session.getTextRange(range);
14305 }
14306 this.$search.set({needle: needle});
14307 }
14308
14309 this.$search.set(options);
14310 if (!options.start)
14311 this.$search.set({start: range});
14312
14313 var newRange = this.$search.find(this.session);
14314 if (options.preventScroll)
14315 return newRange;
14316 if (newRange) {
14317 this.revealRange(newRange, animate);
14318 return newRange;
14319 }
14320 if (options.backwards)
14321 range.start = range.end;
14322 else
14323 range.end = range.start;
14324 this.selection.setRange(range);
14325 };
14326 this.findNext = function(options, animate) {
14327 this.find({skipCurrent: true, backwards: false}, options, animate);
14328 };
14329 this.findPrevious = function(options, animate) {
14330 this.find(options, {skipCurrent: true, backwards: true}, animate);
14331 };
14332
14333 this.revealRange = function(range, animate) {
14334 this.$blockScrolling += 1;
14335 this.session.unfold(range);
14336 this.selection.setSelectionRange(range);
14337 this.$blockScrolling -= 1;
14338
14339 var scrollTop = this.renderer.scrollTop;
14340 this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
14341 if (animate !== false)
14342 this.renderer.animateScrolling(scrollTop);
14343 };
14344 this.undo = function() {
14345 this.$blockScrolling++;
14346 this.session.getUndoManager().undo();
14347 this.$blockScrolling--;
14348 this.renderer.scrollCursorIntoView(null, 0.5);
14349 };
14350 this.redo = function() {
14351 this.$blockScrolling++;
14352 this.session.getUndoManager().redo();
14353 this.$blockScrolling--;
14354 this.renderer.scrollCursorIntoView(null, 0.5);
14355 };
14356 this.destroy = function() {
14357 this.renderer.destroy();
14358 this._signal("destroy", this);
14359 if (this.session) {
14360 this.session.destroy();
14361 }
14362 };
14363 this.setAutoScrollEditorIntoView = function(enable) {
14364 if (!enable)
14365 return;
14366 var rect;
14367 var self = this;
14368 var shouldScroll = false;
14369 if (!this.$scrollAnchor)
14370 this.$scrollAnchor = document.createElement("div");
14371 var scrollAnchor = this.$scrollAnchor;
14372 scrollAnchor.style.cssText = "position:absolute";
14373 this.container.insertBefore(scrollAnchor, this.container.firstChild);
14374 var onChangeSelection = this.on("changeSelection", function() {
14375 shouldScroll = true;
14376 });
14377 var onBeforeRender = this.renderer.on("beforeRender", function() {
14378 if (shouldScroll)
14379 rect = self.renderer.container.getBoundingClientRect();
14380 });
14381 var onAfterRender = this.renderer.on("afterRender", function() {
14382 if (shouldScroll && rect && (self.isFocused()
14383 || self.searchBox && self.searchBox.isFocused())
14384 ) {
14385 var renderer = self.renderer;
14386 var pos = renderer.$cursorLayer.$pixelPos;
14387 var config = renderer.layerConfig;
14388 var top = pos.top - config.offset;
14389 if (pos.top >= 0 && top + rect.top < 0) {
14390 shouldScroll = true;
14391 } else if (pos.top < config.height &&
14392 pos.top + rect.top + config.lineHeight > window.innerHeight) {
14393 shouldScroll = false;
14394 } else {
14395 shouldScroll = null;
14396 }
14397 if (shouldScroll != null) {
14398 scrollAnchor.style.top = top + "px";
14399 scrollAnchor.style.left = pos.left + "px";
14400 scrollAnchor.style.height = config.lineHeight + "px";
14401 scrollAnchor.scrollIntoView(shouldScroll);
14402 }
14403 shouldScroll = rect = null;
14404 }
14405 });
14406 this.setAutoScrollEditorIntoView = function(enable) {
14407 if (enable)
14408 return;
14409 delete this.setAutoScrollEditorIntoView;
14410 this.off("changeSelection", onChangeSelection);
14411 this.renderer.off("afterRender", onAfterRender);
14412 this.renderer.off("beforeRender", onBeforeRender);
14413 };
14414 };
14415
14416
14417 this.$resetCursorStyle = function() {
14418 var style = this.$cursorStyle || "ace";
14419 var cursorLayer = this.renderer.$cursorLayer;
14420 if (!cursorLayer)
14421 return;
14422 cursorLayer.setSmoothBlinking(/smooth/.test(style));
14423 cursorLayer.isBlinking = !this.$readOnly && style != "wide";
14424 dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
14425 };
14426
14427}).call(Editor.prototype);
14428
14429
14430
14431config.defineOptions(Editor.prototype, "editor", {
14432 selectionStyle: {
14433 set: function(style) {
14434 this.onSelectionChange();
14435 this._signal("changeSelectionStyle", {data: style});
14436 },
14437 initialValue: "line"
14438 },
14439 highlightActiveLine: {
14440 set: function() {this.$updateHighlightActiveLine();},
14441 initialValue: true
14442 },
14443 highlightSelectedWord: {
14444 set: function(shouldHighlight) {this.$onSelectionChange();},
14445 initialValue: true
14446 },
14447 readOnly: {
14448 set: function(readOnly) {
14449 this.$resetCursorStyle();
14450 },
14451 initialValue: false
14452 },
14453 cursorStyle: {
14454 set: function(val) { this.$resetCursorStyle(); },
14455 values: ["ace", "slim", "smooth", "wide"],
14456 initialValue: "ace"
14457 },
14458 mergeUndoDeltas: {
14459 values: [false, true, "always"],
14460 initialValue: true
14461 },
14462 behavioursEnabled: {initialValue: true},
14463 wrapBehavioursEnabled: {initialValue: true},
14464 autoScrollEditorIntoView: {
14465 set: function(val) {this.setAutoScrollEditorIntoView(val);}
14466 },
14467 keyboardHandler: {
14468 set: function(val) { this.setKeyboardHandler(val); },
14469 get: function() { return this.keybindingId; },
14470 handlesSet: true
14471 },
14472
14473 hScrollBarAlwaysVisible: "renderer",
14474 vScrollBarAlwaysVisible: "renderer",
14475 highlightGutterLine: "renderer",
14476 animatedScroll: "renderer",
14477 showInvisibles: "renderer",
14478 showPrintMargin: "renderer",
14479 printMarginColumn: "renderer",
14480 printMargin: "renderer",
14481 fadeFoldWidgets: "renderer",
14482 showFoldWidgets: "renderer",
14483 showLineNumbers: "renderer",
14484 showGutter: "renderer",
14485 displayIndentGuides: "renderer",
14486 fontSize: "renderer",
14487 fontFamily: "renderer",
14488 maxLines: "renderer",
14489 minLines: "renderer",
14490 scrollPastEnd: "renderer",
14491 fixedWidthGutter: "renderer",
14492 theme: "renderer",
14493
14494 scrollSpeed: "$mouseHandler",
14495 dragDelay: "$mouseHandler",
14496 dragEnabled: "$mouseHandler",
14497 focusTimout: "$mouseHandler",
14498 tooltipFollowsMouse: "$mouseHandler",
14499
14500 firstLineNumber: "session",
14501 overwrite: "session",
14502 newLineMode: "session",
14503 useWorker: "session",
14504 useSoftTabs: "session",
14505 tabSize: "session",
14506 wrap: "session",
14507 indentedSoftWrap: "session",
14508 foldStyle: "session",
14509 mode: "session"
14510});
14511
14512exports.Editor = Editor;
14513});
14514
14515ace.define("ace/undomanager",["require","exports","module"], function(acequire, exports, module) {
14516var UndoManager = function() {
14517 this.reset();
14518};
14519
14520(function() {
14521 this.execute = function(options) {
14522 var deltaSets = options.args[0];
14523 this.$doc = options.args[1];
14524 if (options.merge && this.hasUndo()){
14525 this.dirtyCounter--;
14526 deltaSets = this.$undoStack.pop().concat(deltaSets);
14527 }
14528 this.$undoStack.push(deltaSets);
14529 this.$redoStack = [];
14530 if (this.dirtyCounter < 0) {
14531 this.dirtyCounter = NaN;
14532 }
14533 this.dirtyCounter++;
14534 };
14535 this.undo = function(dontSelect) {
14536 var deltaSets = this.$undoStack.pop();
14537 var undoSelectionRange = null;
14538 if (deltaSets) {
14539 undoSelectionRange = this.$doc.undoChanges(deltaSets, dontSelect);
14540 this.$redoStack.push(deltaSets);
14541 this.dirtyCounter--;
14542 }
14543
14544 return undoSelectionRange;
14545 };
14546 this.redo = function(dontSelect) {
14547 var deltaSets = this.$redoStack.pop();
14548 var redoSelectionRange = null;
14549 if (deltaSets) {
14550 redoSelectionRange =
14551 this.$doc.redoChanges(this.$deserializeDeltas(deltaSets), dontSelect);
14552 this.$undoStack.push(deltaSets);
14553 this.dirtyCounter++;
14554 }
14555 return redoSelectionRange;
14556 };
14557 this.reset = function() {
14558 this.$undoStack = [];
14559 this.$redoStack = [];
14560 this.dirtyCounter = 0;
14561 };
14562 this.hasUndo = function() {
14563 return this.$undoStack.length > 0;
14564 };
14565 this.hasRedo = function() {
14566 return this.$redoStack.length > 0;
14567 };
14568 this.markClean = function() {
14569 this.dirtyCounter = 0;
14570 };
14571 this.isClean = function() {
14572 return this.dirtyCounter === 0;
14573 };
14574 this.$serializeDeltas = function(deltaSets) {
14575 return cloneDeltaSetsObj(deltaSets, $serializeDelta);
14576 };
14577 this.$deserializeDeltas = function(deltaSets) {
14578 return cloneDeltaSetsObj(deltaSets, $deserializeDelta);
14579 };
14580
14581 function $serializeDelta(delta){
14582 return {
14583 action: delta.action,
14584 start: delta.start,
14585 end: delta.end,
14586 lines: delta.lines.length == 1 ? null : delta.lines,
14587 text: delta.lines.length == 1 ? delta.lines[0] : null
14588 };
14589 }
14590
14591 function $deserializeDelta(delta) {
14592 return {
14593 action: delta.action,
14594 start: delta.start,
14595 end: delta.end,
14596 lines: delta.lines || [delta.text]
14597 };
14598 }
14599
14600 function cloneDeltaSetsObj(deltaSets_old, fnGetModifiedDelta) {
14601 var deltaSets_new = new Array(deltaSets_old.length);
14602 for (var i = 0; i < deltaSets_old.length; i++) {
14603 var deltaSet_old = deltaSets_old[i];
14604 var deltaSet_new = { group: deltaSet_old.group, deltas: new Array(deltaSet_old.length)};
14605
14606 for (var j = 0; j < deltaSet_old.deltas.length; j++) {
14607 var delta_old = deltaSet_old.deltas[j];
14608 deltaSet_new.deltas[j] = fnGetModifiedDelta(delta_old);
14609 }
14610
14611 deltaSets_new[i] = deltaSet_new;
14612 }
14613 return deltaSets_new;
14614 }
14615
14616}).call(UndoManager.prototype);
14617
14618exports.UndoManager = UndoManager;
14619});
14620
14621ace.define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"], function(acequire, exports, module) {
14622
14623var dom = acequire("../lib/dom");
14624var oop = acequire("../lib/oop");
14625var lang = acequire("../lib/lang");
14626var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
14627
14628var Gutter = function(parentEl) {
14629 this.element = dom.createElement("div");
14630 this.element.className = "ace_layer ace_gutter-layer";
14631 parentEl.appendChild(this.element);
14632 this.setShowFoldWidgets(this.$showFoldWidgets);
14633
14634 this.gutterWidth = 0;
14635
14636 this.$annotations = [];
14637 this.$updateAnnotations = this.$updateAnnotations.bind(this);
14638
14639 this.$cells = [];
14640};
14641
14642(function() {
14643
14644 oop.implement(this, EventEmitter);
14645
14646 this.setSession = function(session) {
14647 if (this.session)
14648 this.session.removeEventListener("change", this.$updateAnnotations);
14649 this.session = session;
14650 if (session)
14651 session.on("change", this.$updateAnnotations);
14652 };
14653
14654 this.addGutterDecoration = function(row, className){
14655 if (window.console)
14656 console.warn && console.warn("deprecated use session.addGutterDecoration");
14657 this.session.addGutterDecoration(row, className);
14658 };
14659
14660 this.removeGutterDecoration = function(row, className){
14661 if (window.console)
14662 console.warn && console.warn("deprecated use session.removeGutterDecoration");
14663 this.session.removeGutterDecoration(row, className);
14664 };
14665
14666 this.setAnnotations = function(annotations) {
14667 this.$annotations = [];
14668 for (var i = 0; i < annotations.length; i++) {
14669 var annotation = annotations[i];
14670 var row = annotation.row;
14671 var rowInfo = this.$annotations[row];
14672 if (!rowInfo)
14673 rowInfo = this.$annotations[row] = {text: []};
14674
14675 var annoText = annotation.text;
14676 annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || "";
14677
14678 if (rowInfo.text.indexOf(annoText) === -1)
14679 rowInfo.text.push(annoText);
14680
14681 var type = annotation.type;
14682 if (type == "error")
14683 rowInfo.className = " ace_error";
14684 else if (type == "warning" && rowInfo.className != " ace_error")
14685 rowInfo.className = " ace_warning";
14686 else if (type == "info" && (!rowInfo.className))
14687 rowInfo.className = " ace_info";
14688 }
14689 };
14690
14691 this.$updateAnnotations = function (delta) {
14692 if (!this.$annotations.length)
14693 return;
14694 var firstRow = delta.start.row;
14695 var len = delta.end.row - firstRow;
14696 if (len === 0) ; else if (delta.action == 'remove') {
14697 this.$annotations.splice(firstRow, len + 1, null);
14698 } else {
14699 var args = new Array(len + 1);
14700 args.unshift(firstRow, 1);
14701 this.$annotations.splice.apply(this.$annotations, args);
14702 }
14703 };
14704
14705 this.update = function(config) {
14706 var session = this.session;
14707 var firstRow = config.firstRow;
14708 var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar
14709 session.getLength() - 1);
14710 var fold = session.getNextFoldLine(firstRow);
14711 var foldStart = fold ? fold.start.row : Infinity;
14712 var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
14713 var breakpoints = session.$breakpoints;
14714 var decorations = session.$decorations;
14715 var firstLineNumber = session.$firstLineNumber;
14716 var lastLineNumber = 0;
14717
14718 var gutterRenderer = session.gutterRenderer || this.$renderer;
14719
14720 var cell = null;
14721 var index = -1;
14722 var row = firstRow;
14723 while (true) {
14724 if (row > foldStart) {
14725 row = fold.end.row + 1;
14726 fold = session.getNextFoldLine(row, fold);
14727 foldStart = fold ? fold.start.row : Infinity;
14728 }
14729 if (row > lastRow) {
14730 while (this.$cells.length > index + 1) {
14731 cell = this.$cells.pop();
14732 this.element.removeChild(cell.element);
14733 }
14734 break;
14735 }
14736
14737 cell = this.$cells[++index];
14738 if (!cell) {
14739 cell = {element: null, textNode: null, foldWidget: null};
14740 cell.element = dom.createElement("div");
14741 cell.textNode = document.createTextNode('');
14742 cell.element.appendChild(cell.textNode);
14743 this.element.appendChild(cell.element);
14744 this.$cells[index] = cell;
14745 }
14746
14747 var className = "ace_gutter-cell ";
14748 if (breakpoints[row])
14749 className += breakpoints[row];
14750 if (decorations[row])
14751 className += decorations[row];
14752 if (this.$annotations[row])
14753 className += this.$annotations[row].className;
14754 if (cell.element.className != className)
14755 cell.element.className = className;
14756
14757 var height = session.getRowLength(row) * config.lineHeight + "px";
14758 if (height != cell.element.style.height)
14759 cell.element.style.height = height;
14760
14761 if (foldWidgets) {
14762 var c = foldWidgets[row];
14763 if (c == null)
14764 c = foldWidgets[row] = session.getFoldWidget(row);
14765 }
14766
14767 if (c) {
14768 if (!cell.foldWidget) {
14769 cell.foldWidget = dom.createElement("span");
14770 cell.element.appendChild(cell.foldWidget);
14771 }
14772 var className = "ace_fold-widget ace_" + c;
14773 if (c == "start" && row == foldStart && row < fold.end.row)
14774 className += " ace_closed";
14775 else
14776 className += " ace_open";
14777 if (cell.foldWidget.className != className)
14778 cell.foldWidget.className = className;
14779
14780 var height = config.lineHeight + "px";
14781 if (cell.foldWidget.style.height != height)
14782 cell.foldWidget.style.height = height;
14783 } else {
14784 if (cell.foldWidget) {
14785 cell.element.removeChild(cell.foldWidget);
14786 cell.foldWidget = null;
14787 }
14788 }
14789
14790 var text = lastLineNumber = gutterRenderer
14791 ? gutterRenderer.getText(session, row)
14792 : row + firstLineNumber;
14793 if (text !== cell.textNode.data)
14794 cell.textNode.data = text;
14795
14796 row++;
14797 }
14798
14799 this.element.style.height = config.minHeight + "px";
14800
14801 if (this.$fixedWidth || session.$useWrapMode)
14802 lastLineNumber = session.getLength() + firstLineNumber;
14803
14804 var gutterWidth = gutterRenderer
14805 ? gutterRenderer.getWidth(session, lastLineNumber, config)
14806 : lastLineNumber.toString().length * config.characterWidth;
14807
14808 var padding = this.$padding || this.$computePadding();
14809 gutterWidth += padding.left + padding.right;
14810 if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {
14811 this.gutterWidth = gutterWidth;
14812 this.element.style.width = Math.ceil(this.gutterWidth) + "px";
14813 this._emit("changeGutterWidth", gutterWidth);
14814 }
14815 };
14816
14817 this.$fixedWidth = false;
14818
14819 this.$showLineNumbers = true;
14820 this.$renderer = "";
14821 this.setShowLineNumbers = function(show) {
14822 this.$renderer = !show && {
14823 getWidth: function() {return "";},
14824 getText: function() {return "";}
14825 };
14826 };
14827
14828 this.getShowLineNumbers = function() {
14829 return this.$showLineNumbers;
14830 };
14831
14832 this.$showFoldWidgets = true;
14833 this.setShowFoldWidgets = function(show) {
14834 if (show)
14835 dom.addCssClass(this.element, "ace_folding-enabled");
14836 else
14837 dom.removeCssClass(this.element, "ace_folding-enabled");
14838
14839 this.$showFoldWidgets = show;
14840 this.$padding = null;
14841 };
14842
14843 this.getShowFoldWidgets = function() {
14844 return this.$showFoldWidgets;
14845 };
14846
14847 this.$computePadding = function() {
14848 if (!this.element.firstChild)
14849 return {left: 0, right: 0};
14850 var style = dom.computedStyle(this.element.firstChild);
14851 this.$padding = {};
14852 this.$padding.left = parseInt(style.paddingLeft) + 1 || 0;
14853 this.$padding.right = parseInt(style.paddingRight) || 0;
14854 return this.$padding;
14855 };
14856
14857 this.getRegion = function(point) {
14858 var padding = this.$padding || this.$computePadding();
14859 var rect = this.element.getBoundingClientRect();
14860 if (point.x < padding.left + rect.left)
14861 return "markers";
14862 if (this.$showFoldWidgets && point.x > rect.right - padding.right)
14863 return "foldWidgets";
14864 };
14865
14866}).call(Gutter.prototype);
14867
14868exports.Gutter = Gutter;
14869
14870});
14871
14872ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"], function(acequire, exports, module) {
14873
14874var Range = acequire("../range").Range;
14875var dom = acequire("../lib/dom");
14876
14877var Marker = function(parentEl) {
14878 this.element = dom.createElement("div");
14879 this.element.className = "ace_layer ace_marker-layer";
14880 parentEl.appendChild(this.element);
14881};
14882
14883(function() {
14884
14885 this.$padding = 0;
14886
14887 this.setPadding = function(padding) {
14888 this.$padding = padding;
14889 };
14890 this.setSession = function(session) {
14891 this.session = session;
14892 };
14893
14894 this.setMarkers = function(markers) {
14895 this.markers = markers;
14896 };
14897
14898 this.update = function(config) {
14899 if (!config) return;
14900
14901 this.config = config;
14902
14903
14904 var html = [];
14905 for (var key in this.markers) {
14906 var marker = this.markers[key];
14907
14908 if (!marker.range) {
14909 marker.update(html, this, this.session, config);
14910 continue;
14911 }
14912
14913 var range = marker.range.clipRows(config.firstRow, config.lastRow);
14914 if (range.isEmpty()) continue;
14915
14916 range = range.toScreenRange(this.session);
14917 if (marker.renderer) {
14918 var top = this.$getTop(range.start.row, config);
14919 var left = this.$padding + (this.session.$bidiHandler.isBidiRow(range.start.row)
14920 ? this.session.$bidiHandler.getPosLeft(range.start.column)
14921 : range.start.column * config.characterWidth);
14922 marker.renderer(html, range, left, top, config);
14923 } else if (marker.type == "fullLine") {
14924 this.drawFullLineMarker(html, range, marker.clazz, config);
14925 } else if (marker.type == "screenLine") {
14926 this.drawScreenLineMarker(html, range, marker.clazz, config);
14927 } else if (range.isMultiLine()) {
14928 if (marker.type == "text")
14929 this.drawTextMarker(html, range, marker.clazz, config);
14930 else
14931 this.drawMultiLineMarker(html, range, marker.clazz, config);
14932 } else {
14933 if (this.session.$bidiHandler.isBidiRow(range.start.row)) {
14934 this.drawBidiSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config);
14935 } else {
14936 this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config);
14937 }
14938 }
14939 }
14940 this.element.innerHTML = html.join("");
14941 };
14942
14943 this.$getTop = function(row, layerConfig) {
14944 return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
14945 };
14946
14947 function getBorderClass(tl, tr, br, bl) {
14948 return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0);
14949 }
14950 this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) {
14951 var session = this.session;
14952 var start = range.start.row;
14953 var end = range.end.row;
14954 var row = start;
14955 var prev = 0;
14956 var curr = 0;
14957 var next = session.getScreenLastRowColumn(row);
14958 var clazzModified = null;
14959 var lineRange = new Range(row, range.start.column, row, curr);
14960 for (; row <= end; row++) {
14961 lineRange.start.row = lineRange.end.row = row;
14962 lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row);
14963 lineRange.end.column = next;
14964 prev = curr;
14965 curr = next;
14966 next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column;
14967 clazzModified = clazz + (row == start ? " ace_start" : "") + " ace_br"
14968 + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end);
14969
14970 if (this.session.$bidiHandler.isBidiRow(row)) {
14971 this.drawBidiSingleLineMarker(stringBuilder, lineRange, clazzModified,
14972 layerConfig, row == end ? 0 : 1, extraStyle);
14973 } else {
14974 this.drawSingleLineMarker(stringBuilder, lineRange, clazzModified,
14975 layerConfig, row == end ? 0 : 1, extraStyle);
14976 }
14977 }
14978 };
14979 this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
14980 var padding = this.$padding;
14981 var height, top, left;
14982 extraStyle = extraStyle || "";
14983 if (this.session.$bidiHandler.isBidiRow(range.start.row)) {
14984 var range1 = range.clone();
14985 range1.end.row = range1.start.row;
14986 range1.end.column = this.session.getLine(range1.start.row).length;
14987 this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br1 ace_start", config, null, extraStyle);
14988 } else {
14989 height = config.lineHeight;
14990 top = this.$getTop(range.start.row, config);
14991 left = padding + range.start.column * config.characterWidth;
14992 stringBuilder.push(
14993 "<div class='", clazz, " ace_br1 ace_start' style='",
14994 "height:", height, "px;",
14995 "right:0;",
14996 "top:", top, "px;",
14997 "left:", left, "px;", extraStyle, "'></div>"
14998 );
14999 }
15000 if (this.session.$bidiHandler.isBidiRow(range.end.row)) {
15001 var range1 = range.clone();
15002 range1.start.row = range1.end.row;
15003 range1.start.column = 0;
15004 this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br12", config, null, extraStyle);
15005 } else {
15006 var width = range.end.column * config.characterWidth;
15007 height = config.lineHeight;
15008 top = this.$getTop(range.end.row, config);
15009 stringBuilder.push(
15010 "<div class='", clazz, " ace_br12' style='",
15011 "height:", height, "px;",
15012 "width:", width, "px;",
15013 "top:", top, "px;",
15014 "left:", padding, "px;", extraStyle, "'></div>"
15015 );
15016 }
15017 height = (range.end.row - range.start.row - 1) * config.lineHeight;
15018 if (height <= 0)
15019 return;
15020 top = this.$getTop(range.start.row + 1, config);
15021
15022 var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8);
15023
15024 stringBuilder.push(
15025 "<div class='", clazz, (radiusClass ? " ace_br" + radiusClass : ""), "' style='",
15026 "height:", height, "px;",
15027 "right:0;",
15028 "top:", top, "px;",
15029 "left:", padding, "px;", extraStyle, "'></div>"
15030 );
15031 };
15032 this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
15033 var height = config.lineHeight;
15034 var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;
15035
15036 var top = this.$getTop(range.start.row, config);
15037 var left = this.$padding + range.start.column * config.characterWidth;
15038
15039 stringBuilder.push(
15040 "<div class='", clazz, "' style='",
15041 "height:", height, "px;",
15042 "width:", width, "px;",
15043 "top:", top, "px;",
15044 "left:", left, "px;", extraStyle || "", "'></div>"
15045 );
15046 };
15047 this.drawBidiSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
15048 var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding;
15049 var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column);
15050
15051 selections.forEach(function(selection) {
15052 stringBuilder.push(
15053 "<div class='", clazz, "' style='",
15054 "height:", height, "px;",
15055 "width:", selection.width + (extraLength || 0), "px;",
15056 "top:", top, "px;",
15057 "left:", padding + selection.left, "px;", extraStyle || "", "'></div>"
15058 );
15059 });
15060 };
15061
15062 this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15063 var top = this.$getTop(range.start.row, config);
15064 var height = config.lineHeight;
15065 if (range.start.row != range.end.row)
15066 height += this.$getTop(range.end.row, config) - top;
15067
15068 stringBuilder.push(
15069 "<div class='", clazz, "' style='",
15070 "height:", height, "px;",
15071 "top:", top, "px;",
15072 "left:0;right:0;", extraStyle || "", "'></div>"
15073 );
15074 };
15075
15076 this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15077 var top = this.$getTop(range.start.row, config);
15078 var height = config.lineHeight;
15079
15080 stringBuilder.push(
15081 "<div class='", clazz, "' style='",
15082 "height:", height, "px;",
15083 "top:", top, "px;",
15084 "left:0;right:0;", extraStyle || "", "'></div>"
15085 );
15086 };
15087
15088}).call(Marker.prototype);
15089
15090exports.Marker = Marker;
15091
15092});
15093
15094ace.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) {
15095
15096var oop = acequire("../lib/oop");
15097var dom = acequire("../lib/dom");
15098var lang = acequire("../lib/lang");
15099acequire("../lib/useragent");
15100var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
15101
15102var Text = function(parentEl) {
15103 this.element = dom.createElement("div");
15104 this.element.className = "ace_layer ace_text-layer";
15105 parentEl.appendChild(this.element);
15106 this.$updateEolChar = this.$updateEolChar.bind(this);
15107};
15108
15109(function() {
15110
15111 oop.implement(this, EventEmitter);
15112
15113 this.EOF_CHAR = "\xB6";
15114 this.EOL_CHAR_LF = "\xAC";
15115 this.EOL_CHAR_CRLF = "\xa4";
15116 this.EOL_CHAR = this.EOL_CHAR_LF;
15117 this.TAB_CHAR = "\u2014"; //"\u21E5";
15118 this.SPACE_CHAR = "\xB7";
15119 this.$padding = 0;
15120
15121 this.$updateEolChar = function() {
15122 var EOL_CHAR = this.session.doc.getNewLineCharacter() == "\n"
15123 ? this.EOL_CHAR_LF
15124 : this.EOL_CHAR_CRLF;
15125 if (this.EOL_CHAR != EOL_CHAR) {
15126 this.EOL_CHAR = EOL_CHAR;
15127 return true;
15128 }
15129 };
15130
15131 this.setPadding = function(padding) {
15132 this.$padding = padding;
15133 this.element.style.padding = "0 " + padding + "px";
15134 };
15135
15136 this.getLineHeight = function() {
15137 return this.$fontMetrics.$characterSize.height || 0;
15138 };
15139
15140 this.getCharacterWidth = function() {
15141 return this.$fontMetrics.$characterSize.width || 0;
15142 };
15143
15144 this.$setFontMetrics = function(measure) {
15145 this.$fontMetrics = measure;
15146 this.$fontMetrics.on("changeCharacterSize", function(e) {
15147 this._signal("changeCharacterSize", e);
15148 }.bind(this));
15149 this.$pollSizeChanges();
15150 };
15151
15152 this.checkForSizeChanges = function() {
15153 this.$fontMetrics.checkForSizeChanges();
15154 };
15155 this.$pollSizeChanges = function() {
15156 return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();
15157 };
15158 this.setSession = function(session) {
15159 this.session = session;
15160 if (session)
15161 this.$computeTabString();
15162 };
15163
15164 this.showInvisibles = false;
15165 this.setShowInvisibles = function(showInvisibles) {
15166 if (this.showInvisibles == showInvisibles)
15167 return false;
15168
15169 this.showInvisibles = showInvisibles;
15170 this.$computeTabString();
15171 return true;
15172 };
15173
15174 this.displayIndentGuides = true;
15175 this.setDisplayIndentGuides = function(display) {
15176 if (this.displayIndentGuides == display)
15177 return false;
15178
15179 this.displayIndentGuides = display;
15180 this.$computeTabString();
15181 return true;
15182 };
15183
15184 this.$tabStrings = [];
15185 this.onChangeTabSize =
15186 this.$computeTabString = function() {
15187 var tabSize = this.session.getTabSize();
15188 this.tabSize = tabSize;
15189 var tabStr = this.$tabStrings = [0];
15190 for (var i = 1; i < tabSize + 1; i++) {
15191 if (this.showInvisibles) {
15192 tabStr.push("<span class='ace_invisible ace_invisible_tab'>"
15193 + lang.stringRepeat(this.TAB_CHAR, i)
15194 + "</span>");
15195 } else {
15196 tabStr.push(lang.stringRepeat(" ", i));
15197 }
15198 }
15199 if (this.displayIndentGuides) {
15200 this.$indentGuideRe = /\s\S| \t|\t |\s$/;
15201 var className = "ace_indent-guide";
15202 var spaceClass = "";
15203 var tabClass = "";
15204 if (this.showInvisibles) {
15205 className += " ace_invisible";
15206 spaceClass = " ace_invisible_space";
15207 tabClass = " ace_invisible_tab";
15208 var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);
15209 var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize);
15210 } else {
15211 var spaceContent = lang.stringRepeat(" ", this.tabSize);
15212 var tabContent = spaceContent;
15213 }
15214
15215 this.$tabStrings[" "] = "<span class='" + className + spaceClass + "'>" + spaceContent + "</span>";
15216 this.$tabStrings["\t"] = "<span class='" + className + tabClass + "'>" + tabContent + "</span>";
15217 }
15218 };
15219
15220 this.updateLines = function(config, firstRow, lastRow) {
15221 if (this.config.lastRow != config.lastRow ||
15222 this.config.firstRow != config.firstRow) {
15223 this.scrollLines(config);
15224 }
15225 this.config = config;
15226
15227 var first = Math.max(firstRow, config.firstRow);
15228 var last = Math.min(lastRow, config.lastRow);
15229
15230 var lineElements = this.element.childNodes;
15231 var lineElementsIdx = 0;
15232
15233 for (var row = config.firstRow; row < first; row++) {
15234 var foldLine = this.session.getFoldLine(row);
15235 if (foldLine) {
15236 if (foldLine.containsRow(first)) {
15237 first = foldLine.start.row;
15238 break;
15239 } else {
15240 row = foldLine.end.row;
15241 }
15242 }
15243 lineElementsIdx ++;
15244 }
15245
15246 var row = first;
15247 var foldLine = this.session.getNextFoldLine(row);
15248 var foldStart = foldLine ? foldLine.start.row : Infinity;
15249
15250 while (true) {
15251 if (row > foldStart) {
15252 row = foldLine.end.row+1;
15253 foldLine = this.session.getNextFoldLine(row, foldLine);
15254 foldStart = foldLine ? foldLine.start.row :Infinity;
15255 }
15256 if (row > last)
15257 break;
15258
15259 var lineElement = lineElements[lineElementsIdx++];
15260 if (lineElement) {
15261 var html = [];
15262 this.$renderLine(
15263 html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
15264 );
15265 lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
15266 lineElement.innerHTML = html.join("");
15267 }
15268 row++;
15269 }
15270 };
15271
15272 this.scrollLines = function(config) {
15273 var oldConfig = this.config;
15274 this.config = config;
15275
15276 if (!oldConfig || oldConfig.lastRow < config.firstRow)
15277 return this.update(config);
15278
15279 if (config.lastRow < oldConfig.firstRow)
15280 return this.update(config);
15281
15282 var el = this.element;
15283 if (oldConfig.firstRow < config.firstRow)
15284 for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
15285 el.removeChild(el.firstChild);
15286
15287 if (oldConfig.lastRow > config.lastRow)
15288 for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
15289 el.removeChild(el.lastChild);
15290
15291 if (config.firstRow < oldConfig.firstRow) {
15292 var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
15293 if (el.firstChild)
15294 el.insertBefore(fragment, el.firstChild);
15295 else
15296 el.appendChild(fragment);
15297 }
15298
15299 if (config.lastRow > oldConfig.lastRow) {
15300 var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);
15301 el.appendChild(fragment);
15302 }
15303 };
15304
15305 this.$renderLinesFragment = function(config, firstRow, lastRow) {
15306 var fragment = this.element.ownerDocument.createDocumentFragment();
15307 var row = firstRow;
15308 var foldLine = this.session.getNextFoldLine(row);
15309 var foldStart = foldLine ? foldLine.start.row : Infinity;
15310
15311 while (true) {
15312 if (row > foldStart) {
15313 row = foldLine.end.row+1;
15314 foldLine = this.session.getNextFoldLine(row, foldLine);
15315 foldStart = foldLine ? foldLine.start.row : Infinity;
15316 }
15317 if (row > lastRow)
15318 break;
15319
15320 var container = dom.createElement("div");
15321
15322 var html = [];
15323 this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
15324 container.innerHTML = html.join("");
15325 if (this.$useLineGroups()) {
15326 container.className = 'ace_line_group';
15327 fragment.appendChild(container);
15328 container.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
15329
15330 } else {
15331 while(container.firstChild)
15332 fragment.appendChild(container.firstChild);
15333 }
15334
15335 row++;
15336 }
15337 return fragment;
15338 };
15339
15340 this.update = function(config) {
15341 this.config = config;
15342
15343 var html = [];
15344 var firstRow = config.firstRow, lastRow = config.lastRow;
15345
15346 var row = firstRow;
15347 var foldLine = this.session.getNextFoldLine(row);
15348 var foldStart = foldLine ? foldLine.start.row : Infinity;
15349
15350 while (true) {
15351 if (row > foldStart) {
15352 row = foldLine.end.row+1;
15353 foldLine = this.session.getNextFoldLine(row, foldLine);
15354 foldStart = foldLine ? foldLine.start.row :Infinity;
15355 }
15356 if (row > lastRow)
15357 break;
15358
15359 if (this.$useLineGroups())
15360 html.push("<div class='ace_line_group' style='height:", config.lineHeight*this.session.getRowLength(row), "px'>");
15361
15362 this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
15363
15364 if (this.$useLineGroups())
15365 html.push("</div>"); // end the line group
15366
15367 row++;
15368 }
15369 this.element.innerHTML = html.join("");
15370 };
15371
15372 this.$textToken = {
15373 "text": true,
15374 "rparen": true,
15375 "lparen": true
15376 };
15377
15378 this.$renderToken = function(stringBuilder, screenColumn, token, value) {
15379 var self = this;
15380 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;
15381 var replaceFunc = function(c, a, b, tabIdx, idx4) {
15382 if (a) {
15383 return self.showInvisibles
15384 ? "<span class='ace_invisible ace_invisible_space'>" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "</span>"
15385 : c;
15386 } else if (c == "&") {
15387 return "&#38;";
15388 } else if (c == "<") {
15389 return "&#60;";
15390 } else if (c == ">") {
15391 return "&#62;";
15392 } else if (c == "\t") {
15393 var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
15394 screenColumn += tabSize - 1;
15395 return self.$tabStrings[tabSize];
15396 } else if (c == "\u3000") {
15397 var classToUse = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk";
15398 var space = self.showInvisibles ? self.SPACE_CHAR : "";
15399 screenColumn += 1;
15400 return "<span class='" + classToUse + "' style='width:" +
15401 (self.config.characterWidth * 2) +
15402 "px'>" + space + "</span>";
15403 } else if (b) {
15404 return "<span class='ace_invisible ace_invisible_space ace_invalid'>" + self.SPACE_CHAR + "</span>";
15405 } else {
15406 screenColumn += 1;
15407 return "<span class='ace_cjk' style='width:" +
15408 (self.config.characterWidth * 2) +
15409 "px'>" + c + "</span>";
15410 }
15411 };
15412
15413 var output = value.replace(replaceReg, replaceFunc);
15414
15415 if (!this.$textToken[token.type]) {
15416 var classes = "ace_" + token.type.replace(/\./g, " ace_");
15417 var style = "";
15418 if (token.type == "fold")
15419 style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' ";
15420 stringBuilder.push("<span class='", classes, "'", style, ">", output, "</span>");
15421 }
15422 else {
15423 stringBuilder.push(output);
15424 }
15425 return screenColumn + value.length;
15426 };
15427
15428 this.renderIndentGuide = function(stringBuilder, value, max) {
15429 var cols = value.search(this.$indentGuideRe);
15430 if (cols <= 0 || cols >= max)
15431 return value;
15432 if (value[0] == " ") {
15433 cols -= cols % this.tabSize;
15434 stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize));
15435 return value.substr(cols);
15436 } else if (value[0] == "\t") {
15437 stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols));
15438 return value.substr(cols);
15439 }
15440 return value;
15441 };
15442
15443 this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
15444 var chars = 0;
15445 var split = 0;
15446 var splitChars = splits[0];
15447 var screenColumn = 0;
15448
15449 for (var i = 0; i < tokens.length; i++) {
15450 var token = tokens[i];
15451 var value = token.value;
15452 if (i == 0 && this.displayIndentGuides) {
15453 chars = value.length;
15454 value = this.renderIndentGuide(stringBuilder, value, splitChars);
15455 if (!value)
15456 continue;
15457 chars -= value.length;
15458 }
15459
15460 if (chars + value.length < splitChars) {
15461 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15462 chars += value.length;
15463 } else {
15464 while (chars + value.length >= splitChars) {
15465 screenColumn = this.$renderToken(
15466 stringBuilder, screenColumn,
15467 token, value.substring(0, splitChars - chars)
15468 );
15469 value = value.substring(splitChars - chars);
15470 chars = splitChars;
15471
15472 if (!onlyContents) {
15473 stringBuilder.push("</div>",
15474 "<div class='ace_line' style='height:",
15475 this.config.lineHeight, "px'>"
15476 );
15477 }
15478
15479 stringBuilder.push(lang.stringRepeat("\xa0", splits.indent));
15480
15481 split ++;
15482 screenColumn = 0;
15483 splitChars = splits[split] || Number.MAX_VALUE;
15484 }
15485 if (value.length != 0) {
15486 chars += value.length;
15487 screenColumn = this.$renderToken(
15488 stringBuilder, screenColumn, token, value
15489 );
15490 }
15491 }
15492 }
15493 };
15494
15495 this.$renderSimpleLine = function(stringBuilder, tokens) {
15496 var screenColumn = 0;
15497 var token = tokens[0];
15498 var value = token.value;
15499 if (this.displayIndentGuides)
15500 value = this.renderIndentGuide(stringBuilder, value);
15501 if (value)
15502 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15503 for (var i = 1; i < tokens.length; i++) {
15504 token = tokens[i];
15505 value = token.value;
15506 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15507 }
15508 };
15509 this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
15510 if (!foldLine && foldLine != false)
15511 foldLine = this.session.getFoldLine(row);
15512
15513 if (foldLine)
15514 var tokens = this.$getFoldLineTokens(row, foldLine);
15515 else
15516 var tokens = this.session.getTokens(row);
15517
15518
15519 if (!onlyContents) {
15520 stringBuilder.push(
15521 "<div class='ace_line' style='height:",
15522 this.config.lineHeight * (
15523 this.$useLineGroups() ? 1 :this.session.getRowLength(row)
15524 ), "px'>"
15525 );
15526 }
15527
15528 if (tokens.length) {
15529 var splits = this.session.getRowSplitData(row);
15530 if (splits && splits.length)
15531 this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
15532 else
15533 this.$renderSimpleLine(stringBuilder, tokens);
15534 }
15535
15536 if (this.showInvisibles) {
15537 if (foldLine)
15538 row = foldLine.end.row;
15539
15540 stringBuilder.push(
15541 "<span class='ace_invisible ace_invisible_eol'>",
15542 row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
15543 "</span>"
15544 );
15545 }
15546 if (!onlyContents)
15547 stringBuilder.push("</div>");
15548 };
15549
15550 this.$getFoldLineTokens = function(row, foldLine) {
15551 var session = this.session;
15552 var renderTokens = [];
15553
15554 function addTokens(tokens, from, to) {
15555 var idx = 0, col = 0;
15556 while ((col + tokens[idx].value.length) < from) {
15557 col += tokens[idx].value.length;
15558 idx++;
15559
15560 if (idx == tokens.length)
15561 return;
15562 }
15563 if (col != from) {
15564 var value = tokens[idx].value.substring(from - col);
15565 if (value.length > (to - from))
15566 value = value.substring(0, to - from);
15567
15568 renderTokens.push({
15569 type: tokens[idx].type,
15570 value: value
15571 });
15572
15573 col = from + value.length;
15574 idx += 1;
15575 }
15576
15577 while (col < to && idx < tokens.length) {
15578 var value = tokens[idx].value;
15579 if (value.length + col > to) {
15580 renderTokens.push({
15581 type: tokens[idx].type,
15582 value: value.substring(0, to - col)
15583 });
15584 } else
15585 renderTokens.push(tokens[idx]);
15586 col += value.length;
15587 idx += 1;
15588 }
15589 }
15590
15591 var tokens = session.getTokens(row);
15592 foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
15593 if (placeholder != null) {
15594 renderTokens.push({
15595 type: "fold",
15596 value: placeholder
15597 });
15598 } else {
15599 if (isNewRow)
15600 tokens = session.getTokens(row);
15601
15602 if (tokens.length)
15603 addTokens(tokens, lastColumn, column);
15604 }
15605 }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
15606
15607 return renderTokens;
15608 };
15609
15610 this.$useLineGroups = function() {
15611 return this.session.getUseWrapMode();
15612 };
15613
15614 this.destroy = function() {
15615 clearInterval(this.$pollSizeChangesTimer);
15616 if (this.$measureNode)
15617 this.$measureNode.parentNode.removeChild(this.$measureNode);
15618 delete this.$measureNode;
15619 };
15620
15621}).call(Text.prototype);
15622
15623exports.Text = Text;
15624
15625});
15626
15627ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) {
15628
15629var dom = acequire("../lib/dom");
15630var isIE8;
15631
15632var Cursor = function(parentEl) {
15633 this.element = dom.createElement("div");
15634 this.element.className = "ace_layer ace_cursor-layer";
15635 parentEl.appendChild(this.element);
15636
15637 if (isIE8 === undefined)
15638 isIE8 = !("opacity" in this.element.style);
15639
15640 this.isVisible = false;
15641 this.isBlinking = true;
15642 this.blinkInterval = 1000;
15643 this.smoothBlinking = false;
15644
15645 this.cursors = [];
15646 this.cursor = this.addCursor();
15647 dom.addCssClass(this.element, "ace_hidden-cursors");
15648 this.$updateCursors = (isIE8
15649 ? this.$updateVisibility
15650 : this.$updateOpacity).bind(this);
15651};
15652
15653(function() {
15654
15655 this.$updateVisibility = function(val) {
15656 var cursors = this.cursors;
15657 for (var i = cursors.length; i--; )
15658 cursors[i].style.visibility = val ? "" : "hidden";
15659 };
15660 this.$updateOpacity = function(val) {
15661 var cursors = this.cursors;
15662 for (var i = cursors.length; i--; )
15663 cursors[i].style.opacity = val ? "" : "0";
15664 };
15665
15666
15667 this.$padding = 0;
15668 this.setPadding = function(padding) {
15669 this.$padding = padding;
15670 };
15671
15672 this.setSession = function(session) {
15673 this.session = session;
15674 };
15675
15676 this.setBlinking = function(blinking) {
15677 if (blinking != this.isBlinking){
15678 this.isBlinking = blinking;
15679 this.restartTimer();
15680 }
15681 };
15682
15683 this.setBlinkInterval = function(blinkInterval) {
15684 if (blinkInterval != this.blinkInterval){
15685 this.blinkInterval = blinkInterval;
15686 this.restartTimer();
15687 }
15688 };
15689
15690 this.setSmoothBlinking = function(smoothBlinking) {
15691 if (smoothBlinking != this.smoothBlinking && !isIE8) {
15692 this.smoothBlinking = smoothBlinking;
15693 dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking);
15694 this.$updateCursors(true);
15695 this.$updateCursors = (this.$updateOpacity).bind(this);
15696 this.restartTimer();
15697 }
15698 };
15699
15700 this.addCursor = function() {
15701 var el = dom.createElement("div");
15702 el.className = "ace_cursor";
15703 this.element.appendChild(el);
15704 this.cursors.push(el);
15705 return el;
15706 };
15707
15708 this.removeCursor = function() {
15709 if (this.cursors.length > 1) {
15710 var el = this.cursors.pop();
15711 el.parentNode.removeChild(el);
15712 return el;
15713 }
15714 };
15715
15716 this.hideCursor = function() {
15717 this.isVisible = false;
15718 dom.addCssClass(this.element, "ace_hidden-cursors");
15719 this.restartTimer();
15720 };
15721
15722 this.showCursor = function() {
15723 this.isVisible = true;
15724 dom.removeCssClass(this.element, "ace_hidden-cursors");
15725 this.restartTimer();
15726 };
15727
15728 this.restartTimer = function() {
15729 var update = this.$updateCursors;
15730 clearInterval(this.intervalId);
15731 clearTimeout(this.timeoutId);
15732 if (this.smoothBlinking) {
15733 dom.removeCssClass(this.element, "ace_smooth-blinking");
15734 }
15735
15736 update(true);
15737
15738 if (!this.isBlinking || !this.blinkInterval || !this.isVisible)
15739 return;
15740
15741 if (this.smoothBlinking) {
15742 setTimeout(function(){
15743 dom.addCssClass(this.element, "ace_smooth-blinking");
15744 }.bind(this));
15745 }
15746
15747 var blink = function(){
15748 this.timeoutId = setTimeout(function() {
15749 update(false);
15750 }, 0.6 * this.blinkInterval);
15751 }.bind(this);
15752
15753 this.intervalId = setInterval(function() {
15754 update(true);
15755 blink();
15756 }, this.blinkInterval);
15757
15758 blink();
15759 };
15760
15761 this.getPixelPosition = function(position, onScreen) {
15762 if (!this.config || !this.session)
15763 return {left : 0, top : 0};
15764
15765 if (!position)
15766 position = this.session.selection.getCursor();
15767 var pos = this.session.documentToScreenPosition(position);
15768 var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row)
15769 ? this.session.$bidiHandler.getPosLeft(pos.column)
15770 : pos.column * this.config.characterWidth);
15771
15772 var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
15773 this.config.lineHeight;
15774
15775 return {left : cursorLeft, top : cursorTop};
15776 };
15777
15778 this.update = function(config) {
15779 this.config = config;
15780
15781 var selections = this.session.$selectionMarkers;
15782 var i = 0, cursorIndex = 0;
15783
15784 if (selections === undefined || selections.length === 0){
15785 selections = [{cursor: null}];
15786 }
15787
15788 for (var i = 0, n = selections.length; i < n; i++) {
15789 var pixelPos = this.getPixelPosition(selections[i].cursor, true);
15790 if ((pixelPos.top > config.height + config.offset ||
15791 pixelPos.top < 0) && i > 1) {
15792 continue;
15793 }
15794
15795 var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
15796
15797 if (!this.drawCursor) {
15798 style.left = pixelPos.left + "px";
15799 style.top = pixelPos.top + "px";
15800 style.width = config.characterWidth + "px";
15801 style.height = config.lineHeight + "px";
15802 } else {
15803 this.drawCursor(style, pixelPos, config, selections[i], this.session);
15804 }
15805 }
15806 while (this.cursors.length > cursorIndex)
15807 this.removeCursor();
15808
15809 var overwrite = this.session.getOverwrite();
15810 this.$setOverwrite(overwrite);
15811 this.$pixelPos = pixelPos;
15812 this.restartTimer();
15813 };
15814
15815 this.drawCursor = null;
15816
15817 this.$setOverwrite = function(overwrite) {
15818 if (overwrite != this.overwrite) {
15819 this.overwrite = overwrite;
15820 if (overwrite)
15821 dom.addCssClass(this.element, "ace_overwrite-cursors");
15822 else
15823 dom.removeCssClass(this.element, "ace_overwrite-cursors");
15824 }
15825 };
15826
15827 this.destroy = function() {
15828 clearInterval(this.intervalId);
15829 clearTimeout(this.timeoutId);
15830 };
15831
15832}).call(Cursor.prototype);
15833
15834exports.Cursor = Cursor;
15835
15836});
15837
15838ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"], function(acequire, exports, module) {
15839
15840var oop = acequire("./lib/oop");
15841var dom = acequire("./lib/dom");
15842var event = acequire("./lib/event");
15843var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
15844var MAX_SCROLL_H = 0x8000;
15845var ScrollBar = function(parent) {
15846 this.element = dom.createElement("div");
15847 this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix;
15848
15849 this.inner = dom.createElement("div");
15850 this.inner.className = "ace_scrollbar-inner";
15851 this.element.appendChild(this.inner);
15852
15853 parent.appendChild(this.element);
15854
15855 this.setVisible(false);
15856 this.skipEvent = false;
15857
15858 event.addListener(this.element, "scroll", this.onScroll.bind(this));
15859 event.addListener(this.element, "mousedown", event.preventDefault);
15860};
15861
15862(function() {
15863 oop.implement(this, EventEmitter);
15864
15865 this.setVisible = function(isVisible) {
15866 this.element.style.display = isVisible ? "" : "none";
15867 this.isVisible = isVisible;
15868 this.coeff = 1;
15869 };
15870}).call(ScrollBar.prototype);
15871var VScrollBar = function(parent, renderer) {
15872 ScrollBar.call(this, parent);
15873 this.scrollTop = 0;
15874 this.scrollHeight = 0;
15875 renderer.$scrollbarWidth =
15876 this.width = dom.scrollbarWidth(parent.ownerDocument);
15877 this.inner.style.width =
15878 this.element.style.width = (this.width || 15) + 5 + "px";
15879 this.$minWidth = 0;
15880};
15881
15882oop.inherits(VScrollBar, ScrollBar);
15883
15884(function() {
15885
15886 this.classSuffix = '-v';
15887 this.onScroll = function() {
15888 if (!this.skipEvent) {
15889 this.scrollTop = this.element.scrollTop;
15890 if (this.coeff != 1) {
15891 var h = this.element.clientHeight / this.scrollHeight;
15892 this.scrollTop = this.scrollTop * (1 - h) / (this.coeff - h);
15893 }
15894 this._emit("scroll", {data: this.scrollTop});
15895 }
15896 this.skipEvent = false;
15897 };
15898 this.getWidth = function() {
15899 return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0);
15900 };
15901 this.setHeight = function(height) {
15902 this.element.style.height = height + "px";
15903 };
15904 this.setInnerHeight =
15905 this.setScrollHeight = function(height) {
15906 this.scrollHeight = height;
15907 if (height > MAX_SCROLL_H) {
15908 this.coeff = MAX_SCROLL_H / height;
15909 height = MAX_SCROLL_H;
15910 } else if (this.coeff != 1) {
15911 this.coeff = 1;
15912 }
15913 this.inner.style.height = height + "px";
15914 };
15915 this.setScrollTop = function(scrollTop) {
15916 if (this.scrollTop != scrollTop) {
15917 this.skipEvent = true;
15918 this.scrollTop = scrollTop;
15919 this.element.scrollTop = scrollTop * this.coeff;
15920 }
15921 };
15922
15923}).call(VScrollBar.prototype);
15924var HScrollBar = function(parent, renderer) {
15925 ScrollBar.call(this, parent);
15926 this.scrollLeft = 0;
15927 this.height = renderer.$scrollbarWidth;
15928 this.inner.style.height =
15929 this.element.style.height = (this.height || 15) + 5 + "px";
15930};
15931
15932oop.inherits(HScrollBar, ScrollBar);
15933
15934(function() {
15935
15936 this.classSuffix = '-h';
15937 this.onScroll = function() {
15938 if (!this.skipEvent) {
15939 this.scrollLeft = this.element.scrollLeft;
15940 this._emit("scroll", {data: this.scrollLeft});
15941 }
15942 this.skipEvent = false;
15943 };
15944 this.getHeight = function() {
15945 return this.isVisible ? this.height : 0;
15946 };
15947 this.setWidth = function(width) {
15948 this.element.style.width = width + "px";
15949 };
15950 this.setInnerWidth = function(width) {
15951 this.inner.style.width = width + "px";
15952 };
15953 this.setScrollWidth = function(width) {
15954 this.inner.style.width = width + "px";
15955 };
15956 this.setScrollLeft = function(scrollLeft) {
15957 if (this.scrollLeft != scrollLeft) {
15958 this.skipEvent = true;
15959 this.scrollLeft = this.element.scrollLeft = scrollLeft;
15960 }
15961 };
15962
15963}).call(HScrollBar.prototype);
15964
15965
15966exports.ScrollBar = VScrollBar; // backward compatibility
15967exports.ScrollBarV = VScrollBar; // backward compatibility
15968exports.ScrollBarH = HScrollBar; // backward compatibility
15969
15970exports.VScrollBar = VScrollBar;
15971exports.HScrollBar = HScrollBar;
15972});
15973
15974ace.define("ace/renderloop",["require","exports","module","ace/lib/event"], function(acequire, exports, module) {
15975
15976var event = acequire("./lib/event");
15977
15978
15979var RenderLoop = function(onRender, win) {
15980 this.onRender = onRender;
15981 this.pending = false;
15982 this.changes = 0;
15983 this.window = win || window;
15984};
15985
15986(function() {
15987
15988
15989 this.schedule = function(change) {
15990 this.changes = this.changes | change;
15991 if (!this.pending && this.changes) {
15992 this.pending = true;
15993 var _self = this;
15994 event.nextFrame(function() {
15995 _self.pending = false;
15996 var changes;
15997 while (changes = _self.changes) {
15998 _self.changes = 0;
15999 _self.onRender(changes);
16000 }
16001 }, this.window);
16002 }
16003 };
16004
16005}).call(RenderLoop.prototype);
16006
16007exports.RenderLoop = RenderLoop;
16008});
16009
16010ace.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) {
16011
16012var oop = acequire("../lib/oop");
16013var dom = acequire("../lib/dom");
16014var lang = acequire("../lib/lang");
16015var useragent = acequire("../lib/useragent");
16016var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
16017
16018var CHAR_COUNT = 0;
16019
16020var FontMetrics = exports.FontMetrics = function(parentEl) {
16021 this.el = dom.createElement("div");
16022 this.$setMeasureNodeStyles(this.el.style, true);
16023
16024 this.$main = dom.createElement("div");
16025 this.$setMeasureNodeStyles(this.$main.style);
16026
16027 this.$measureNode = dom.createElement("div");
16028 this.$setMeasureNodeStyles(this.$measureNode.style);
16029
16030
16031 this.el.appendChild(this.$main);
16032 this.el.appendChild(this.$measureNode);
16033 parentEl.appendChild(this.el);
16034
16035 if (!CHAR_COUNT)
16036 this.$testFractionalRect();
16037 this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT);
16038
16039 this.$characterSize = {width: 0, height: 0};
16040 this.checkForSizeChanges();
16041};
16042
16043(function() {
16044
16045 oop.implement(this, EventEmitter);
16046
16047 this.$characterSize = {width: 0, height: 0};
16048
16049 this.$testFractionalRect = function() {
16050 var el = dom.createElement("div");
16051 this.$setMeasureNodeStyles(el.style);
16052 el.style.width = "0.2px";
16053 document.documentElement.appendChild(el);
16054 var w = el.getBoundingClientRect().width;
16055 if (w > 0 && w < 1)
16056 CHAR_COUNT = 50;
16057 else
16058 CHAR_COUNT = 100;
16059 el.parentNode.removeChild(el);
16060 };
16061
16062 this.$setMeasureNodeStyles = function(style, isRoot) {
16063 style.width = style.height = "auto";
16064 style.left = style.top = "0px";
16065 style.visibility = "hidden";
16066 style.position = "absolute";
16067 style.whiteSpace = "pre";
16068
16069 if (useragent.isIE < 8) {
16070 style["font-family"] = "inherit";
16071 } else {
16072 style.font = "inherit";
16073 }
16074 style.overflow = isRoot ? "hidden" : "visible";
16075 };
16076
16077 this.checkForSizeChanges = function() {
16078 var size = this.$measureSizes();
16079 if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
16080 this.$measureNode.style.fontWeight = "bold";
16081 var boldSize = this.$measureSizes();
16082 this.$measureNode.style.fontWeight = "";
16083 this.$characterSize = size;
16084 this.charSizes = Object.create(null);
16085 this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
16086 this._emit("changeCharacterSize", {data: size});
16087 }
16088 };
16089
16090 this.$pollSizeChanges = function() {
16091 if (this.$pollSizeChangesTimer)
16092 return this.$pollSizeChangesTimer;
16093 var self = this;
16094 return this.$pollSizeChangesTimer = setInterval(function() {
16095 self.checkForSizeChanges();
16096 }, 500);
16097 };
16098
16099 this.setPolling = function(val) {
16100 if (val) {
16101 this.$pollSizeChanges();
16102 } else if (this.$pollSizeChangesTimer) {
16103 clearInterval(this.$pollSizeChangesTimer);
16104 this.$pollSizeChangesTimer = 0;
16105 }
16106 };
16107
16108 this.$measureSizes = function() {
16109 if (CHAR_COUNT === 50) {
16110 var rect = null;
16111 try {
16112 rect = this.$measureNode.getBoundingClientRect();
16113 } catch(e) {
16114 rect = {width: 0, height:0 };
16115 }
16116 var size = {
16117 height: rect.height,
16118 width: rect.width / CHAR_COUNT
16119 };
16120 } else {
16121 var size = {
16122 height: this.$measureNode.clientHeight,
16123 width: this.$measureNode.clientWidth / CHAR_COUNT
16124 };
16125 }
16126 if (size.width === 0 || size.height === 0)
16127 return null;
16128 return size;
16129 };
16130
16131 this.$measureCharWidth = function(ch) {
16132 this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT);
16133 var rect = this.$main.getBoundingClientRect();
16134 return rect.width / CHAR_COUNT;
16135 };
16136
16137 this.getCharacterWidth = function(ch) {
16138 var w = this.charSizes[ch];
16139 if (w === undefined) {
16140 w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width;
16141 }
16142 return w;
16143 };
16144
16145 this.destroy = function() {
16146 clearInterval(this.$pollSizeChangesTimer);
16147 if (this.el && this.el.parentNode)
16148 this.el.parentNode.removeChild(this.el);
16149 };
16150
16151}).call(FontMetrics.prototype);
16152
16153});
16154
16155ace.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) {
16156
16157var oop = acequire("./lib/oop");
16158var dom = acequire("./lib/dom");
16159var config = acequire("./config");
16160var useragent = acequire("./lib/useragent");
16161var GutterLayer = acequire("./layer/gutter").Gutter;
16162var MarkerLayer = acequire("./layer/marker").Marker;
16163var TextLayer = acequire("./layer/text").Text;
16164var CursorLayer = acequire("./layer/cursor").Cursor;
16165var HScrollBar = acequire("./scrollbar").HScrollBar;
16166var VScrollBar = acequire("./scrollbar").VScrollBar;
16167var RenderLoop = acequire("./renderloop").RenderLoop;
16168var FontMetrics = acequire("./layer/font_metrics").FontMetrics;
16169var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
16170var editorCss = ".ace_editor {\
16171position: relative;\
16172overflow: hidden;\
16173font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
16174direction: ltr;\
16175text-align: left;\
16176-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\
16177}\
16178.ace_scroller {\
16179position: absolute;\
16180overflow: hidden;\
16181top: 0;\
16182bottom: 0;\
16183background-color: inherit;\
16184-ms-user-select: none;\
16185-moz-user-select: none;\
16186-webkit-user-select: none;\
16187user-select: none;\
16188cursor: text;\
16189}\
16190.ace_content {\
16191position: absolute;\
16192-moz-box-sizing: border-box;\
16193-webkit-box-sizing: border-box;\
16194box-sizing: border-box;\
16195min-width: 100%;\
16196}\
16197.ace_dragging .ace_scroller:before{\
16198position: absolute;\
16199top: 0;\
16200left: 0;\
16201right: 0;\
16202bottom: 0;\
16203content: '';\
16204background: rgba(250, 250, 250, 0.01);\
16205z-index: 1000;\
16206}\
16207.ace_dragging.ace_dark .ace_scroller:before{\
16208background: rgba(0, 0, 0, 0.01);\
16209}\
16210.ace_selecting, .ace_selecting * {\
16211cursor: text !important;\
16212}\
16213.ace_gutter {\
16214position: absolute;\
16215overflow : hidden;\
16216width: auto;\
16217top: 0;\
16218bottom: 0;\
16219left: 0;\
16220cursor: default;\
16221z-index: 4;\
16222-ms-user-select: none;\
16223-moz-user-select: none;\
16224-webkit-user-select: none;\
16225user-select: none;\
16226}\
16227.ace_gutter-active-line {\
16228position: absolute;\
16229left: 0;\
16230right: 0;\
16231}\
16232.ace_scroller.ace_scroll-left {\
16233box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\
16234}\
16235.ace_gutter-cell {\
16236padding-left: 19px;\
16237padding-right: 6px;\
16238background-repeat: no-repeat;\
16239}\
16240.ace_gutter-cell.ace_error {\
16241background-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==\");\
16242background-repeat: no-repeat;\
16243background-position: 2px center;\
16244}\
16245.ace_gutter-cell.ace_warning {\
16246background-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==\");\
16247background-position: 2px center;\
16248}\
16249.ace_gutter-cell.ace_info {\
16250background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\
16251background-position: 2px center;\
16252}\
16253.ace_dark .ace_gutter-cell.ace_info {\
16254background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\
16255}\
16256.ace_scrollbar {\
16257position: absolute;\
16258right: 0;\
16259bottom: 0;\
16260z-index: 6;\
16261}\
16262.ace_scrollbar-inner {\
16263position: absolute;\
16264cursor: text;\
16265left: 0;\
16266top: 0;\
16267}\
16268.ace_scrollbar-v{\
16269overflow-x: hidden;\
16270overflow-y: scroll;\
16271top: 0;\
16272}\
16273.ace_scrollbar-h {\
16274overflow-x: scroll;\
16275overflow-y: hidden;\
16276left: 0;\
16277}\
16278.ace_print-margin {\
16279position: absolute;\
16280height: 100%;\
16281}\
16282.ace_text-input {\
16283position: absolute;\
16284z-index: 0;\
16285width: 0.5em;\
16286height: 1em;\
16287opacity: 0;\
16288background: transparent;\
16289-moz-appearance: none;\
16290appearance: none;\
16291border: none;\
16292resize: none;\
16293outline: none;\
16294overflow: hidden;\
16295font: inherit;\
16296padding: 0 1px;\
16297margin: 0 -1px;\
16298text-indent: -1em;\
16299-ms-user-select: text;\
16300-moz-user-select: text;\
16301-webkit-user-select: text;\
16302user-select: text;\
16303white-space: pre!important;\
16304}\
16305.ace_text-input.ace_composition {\
16306background: inherit;\
16307color: inherit;\
16308z-index: 1000;\
16309opacity: 1;\
16310text-indent: 0;\
16311}\
16312.ace_layer {\
16313z-index: 1;\
16314position: absolute;\
16315overflow: hidden;\
16316word-wrap: normal;\
16317white-space: pre;\
16318height: 100%;\
16319width: 100%;\
16320-moz-box-sizing: border-box;\
16321-webkit-box-sizing: border-box;\
16322box-sizing: border-box;\
16323pointer-events: none;\
16324}\
16325.ace_gutter-layer {\
16326position: relative;\
16327width: auto;\
16328text-align: right;\
16329pointer-events: auto;\
16330}\
16331.ace_text-layer {\
16332font: inherit !important;\
16333}\
16334.ace_cjk {\
16335display: inline-block;\
16336text-align: center;\
16337}\
16338.ace_cursor-layer {\
16339z-index: 4;\
16340}\
16341.ace_cursor {\
16342z-index: 4;\
16343position: absolute;\
16344-moz-box-sizing: border-box;\
16345-webkit-box-sizing: border-box;\
16346box-sizing: border-box;\
16347border-left: 2px solid;\
16348transform: translatez(0);\
16349}\
16350.ace_multiselect .ace_cursor {\
16351border-left-width: 1px;\
16352}\
16353.ace_slim-cursors .ace_cursor {\
16354border-left-width: 1px;\
16355}\
16356.ace_overwrite-cursors .ace_cursor {\
16357border-left-width: 0;\
16358border-bottom: 1px solid;\
16359}\
16360.ace_hidden-cursors .ace_cursor {\
16361opacity: 0.2;\
16362}\
16363.ace_smooth-blinking .ace_cursor {\
16364-webkit-transition: opacity 0.18s;\
16365transition: opacity 0.18s;\
16366}\
16367.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\
16368position: absolute;\
16369z-index: 3;\
16370}\
16371.ace_marker-layer .ace_selection {\
16372position: absolute;\
16373z-index: 5;\
16374}\
16375.ace_marker-layer .ace_bracket {\
16376position: absolute;\
16377z-index: 6;\
16378}\
16379.ace_marker-layer .ace_active-line {\
16380position: absolute;\
16381z-index: 2;\
16382}\
16383.ace_marker-layer .ace_selected-word {\
16384position: absolute;\
16385z-index: 4;\
16386-moz-box-sizing: border-box;\
16387-webkit-box-sizing: border-box;\
16388box-sizing: border-box;\
16389}\
16390.ace_line .ace_fold {\
16391-moz-box-sizing: border-box;\
16392-webkit-box-sizing: border-box;\
16393box-sizing: border-box;\
16394display: inline-block;\
16395height: 11px;\
16396margin-top: -2px;\
16397vertical-align: middle;\
16398background-image:\
16399url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
16400url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\
16401background-repeat: no-repeat, repeat-x;\
16402background-position: center center, top left;\
16403color: transparent;\
16404border: 1px solid black;\
16405border-radius: 2px;\
16406cursor: pointer;\
16407pointer-events: auto;\
16408}\
16409.ace_dark .ace_fold {\
16410}\
16411.ace_fold:hover{\
16412background-image:\
16413url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
16414url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\
16415}\
16416.ace_tooltip {\
16417background-color: #FFF;\
16418background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\
16419background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\
16420border: 1px solid gray;\
16421border-radius: 1px;\
16422box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\
16423color: black;\
16424max-width: 100%;\
16425padding: 3px 4px;\
16426position: fixed;\
16427z-index: 999999;\
16428-moz-box-sizing: border-box;\
16429-webkit-box-sizing: border-box;\
16430box-sizing: border-box;\
16431cursor: default;\
16432white-space: pre;\
16433word-wrap: break-word;\
16434line-height: normal;\
16435font-style: normal;\
16436font-weight: normal;\
16437letter-spacing: normal;\
16438pointer-events: none;\
16439}\
16440.ace_folding-enabled > .ace_gutter-cell {\
16441padding-right: 13px;\
16442}\
16443.ace_fold-widget {\
16444-moz-box-sizing: border-box;\
16445-webkit-box-sizing: border-box;\
16446box-sizing: border-box;\
16447margin: 0 -12px 0 1px;\
16448display: none;\
16449width: 11px;\
16450vertical-align: top;\
16451background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\
16452background-repeat: no-repeat;\
16453background-position: center;\
16454border-radius: 3px;\
16455border: 1px solid transparent;\
16456cursor: pointer;\
16457}\
16458.ace_folding-enabled .ace_fold-widget {\
16459display: inline-block; \
16460}\
16461.ace_fold-widget.ace_end {\
16462background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\
16463}\
16464.ace_fold-widget.ace_closed {\
16465background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\
16466}\
16467.ace_fold-widget:hover {\
16468border: 1px solid rgba(0, 0, 0, 0.3);\
16469background-color: rgba(255, 255, 255, 0.2);\
16470box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
16471}\
16472.ace_fold-widget:active {\
16473border: 1px solid rgba(0, 0, 0, 0.4);\
16474background-color: rgba(0, 0, 0, 0.05);\
16475box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
16476}\
16477.ace_dark .ace_fold-widget {\
16478background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\
16479}\
16480.ace_dark .ace_fold-widget.ace_end {\
16481background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\
16482}\
16483.ace_dark .ace_fold-widget.ace_closed {\
16484background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\
16485}\
16486.ace_dark .ace_fold-widget:hover {\
16487box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
16488background-color: rgba(255, 255, 255, 0.1);\
16489}\
16490.ace_dark .ace_fold-widget:active {\
16491box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
16492}\
16493.ace_fold-widget.ace_invalid {\
16494background-color: #FFB4B4;\
16495border-color: #DE5555;\
16496}\
16497.ace_fade-fold-widgets .ace_fold-widget {\
16498-webkit-transition: opacity 0.4s ease 0.05s;\
16499transition: opacity 0.4s ease 0.05s;\
16500opacity: 0;\
16501}\
16502.ace_fade-fold-widgets:hover .ace_fold-widget {\
16503-webkit-transition: opacity 0.05s ease 0.05s;\
16504transition: opacity 0.05s ease 0.05s;\
16505opacity:1;\
16506}\
16507.ace_underline {\
16508text-decoration: underline;\
16509}\
16510.ace_bold {\
16511font-weight: bold;\
16512}\
16513.ace_nobold .ace_bold {\
16514font-weight: normal;\
16515}\
16516.ace_italic {\
16517font-style: italic;\
16518}\
16519.ace_error-marker {\
16520background-color: rgba(255, 0, 0,0.2);\
16521position: absolute;\
16522z-index: 9;\
16523}\
16524.ace_highlight-marker {\
16525background-color: rgba(255, 255, 0,0.2);\
16526position: absolute;\
16527z-index: 8;\
16528}\
16529.ace_br1 {border-top-left-radius : 3px;}\
16530.ace_br2 {border-top-right-radius : 3px;}\
16531.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}\
16532.ace_br4 {border-bottom-right-radius: 3px;}\
16533.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}\
16534.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}\
16535.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}\
16536.ace_br8 {border-bottom-left-radius : 3px;}\
16537.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}\
16538.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}\
16539.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}\
16540.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16541.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16542.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16543.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16544.ace_text-input-ios {\
16545position: absolute !important;\
16546top: -100000px !important;\
16547left: -100000px !important;\
16548}\
16549";
16550
16551dom.importCssString(editorCss, "ace_editor.css");
16552
16553var VirtualRenderer = function(container, theme) {
16554 var _self = this;
16555
16556 this.container = container || dom.createElement("div");
16557 this.$keepTextAreaAtCursor = !useragent.isOldIE;
16558
16559 dom.addCssClass(this.container, "ace_editor");
16560
16561 this.setTheme(theme);
16562
16563 this.$gutter = dom.createElement("div");
16564 this.$gutter.className = "ace_gutter";
16565 this.container.appendChild(this.$gutter);
16566 this.$gutter.setAttribute("aria-hidden", true);
16567
16568 this.scroller = dom.createElement("div");
16569 this.scroller.className = "ace_scroller";
16570 this.container.appendChild(this.scroller);
16571
16572 this.content = dom.createElement("div");
16573 this.content.className = "ace_content";
16574 this.scroller.appendChild(this.content);
16575
16576 this.$gutterLayer = new GutterLayer(this.$gutter);
16577 this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
16578
16579 this.$markerBack = new MarkerLayer(this.content);
16580
16581 var textLayer = this.$textLayer = new TextLayer(this.content);
16582 this.canvas = textLayer.element;
16583
16584 this.$markerFront = new MarkerLayer(this.content);
16585
16586 this.$cursorLayer = new CursorLayer(this.content);
16587 this.$horizScroll = false;
16588 this.$vScroll = false;
16589
16590 this.scrollBar =
16591 this.scrollBarV = new VScrollBar(this.container, this);
16592 this.scrollBarH = new HScrollBar(this.container, this);
16593 this.scrollBarV.addEventListener("scroll", function(e) {
16594 if (!_self.$scrollAnimation)
16595 _self.session.setScrollTop(e.data - _self.scrollMargin.top);
16596 });
16597 this.scrollBarH.addEventListener("scroll", function(e) {
16598 if (!_self.$scrollAnimation)
16599 _self.session.setScrollLeft(e.data - _self.scrollMargin.left);
16600 });
16601
16602 this.scrollTop = 0;
16603 this.scrollLeft = 0;
16604
16605 this.cursorPos = {
16606 row : 0,
16607 column : 0
16608 };
16609
16610 this.$fontMetrics = new FontMetrics(this.container);
16611 this.$textLayer.$setFontMetrics(this.$fontMetrics);
16612 this.$textLayer.addEventListener("changeCharacterSize", function(e) {
16613 _self.updateCharacterSize();
16614 _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height);
16615 _self._signal("changeCharacterSize", e);
16616 });
16617
16618 this.$size = {
16619 width: 0,
16620 height: 0,
16621 scrollerHeight: 0,
16622 scrollerWidth: 0,
16623 $dirty: true
16624 };
16625
16626 this.layerConfig = {
16627 width : 1,
16628 padding : 0,
16629 firstRow : 0,
16630 firstRowScreen: 0,
16631 lastRow : 0,
16632 lineHeight : 0,
16633 characterWidth : 0,
16634 minHeight : 1,
16635 maxHeight : 1,
16636 offset : 0,
16637 height : 1,
16638 gutterOffset: 1
16639 };
16640
16641 this.scrollMargin = {
16642 left: 0,
16643 right: 0,
16644 top: 0,
16645 bottom: 0,
16646 v: 0,
16647 h: 0
16648 };
16649
16650 this.$loop = new RenderLoop(
16651 this.$renderChanges.bind(this),
16652 this.container.ownerDocument.defaultView
16653 );
16654 this.$loop.schedule(this.CHANGE_FULL);
16655
16656 this.updateCharacterSize();
16657 this.setPadding(4);
16658 config.resetOptions(this);
16659 config._emit("renderer", this);
16660};
16661
16662(function() {
16663
16664 this.CHANGE_CURSOR = 1;
16665 this.CHANGE_MARKER = 2;
16666 this.CHANGE_GUTTER = 4;
16667 this.CHANGE_SCROLL = 8;
16668 this.CHANGE_LINES = 16;
16669 this.CHANGE_TEXT = 32;
16670 this.CHANGE_SIZE = 64;
16671 this.CHANGE_MARKER_BACK = 128;
16672 this.CHANGE_MARKER_FRONT = 256;
16673 this.CHANGE_FULL = 512;
16674 this.CHANGE_H_SCROLL = 1024;
16675
16676 oop.implement(this, EventEmitter);
16677
16678 this.updateCharacterSize = function() {
16679 if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {
16680 this.$allowBoldFonts = this.$textLayer.allowBoldFonts;
16681 this.setStyle("ace_nobold", !this.$allowBoldFonts);
16682 }
16683
16684 this.layerConfig.characterWidth =
16685 this.characterWidth = this.$textLayer.getCharacterWidth();
16686 this.layerConfig.lineHeight =
16687 this.lineHeight = this.$textLayer.getLineHeight();
16688 this.$updatePrintMargin();
16689 };
16690 this.setSession = function(session) {
16691 if (this.session)
16692 this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode);
16693
16694 this.session = session;
16695 if (session && this.scrollMargin.top && session.getScrollTop() <= 0)
16696 session.setScrollTop(-this.scrollMargin.top);
16697
16698 this.$cursorLayer.setSession(session);
16699 this.$markerBack.setSession(session);
16700 this.$markerFront.setSession(session);
16701 this.$gutterLayer.setSession(session);
16702 this.$textLayer.setSession(session);
16703 if (!session)
16704 return;
16705
16706 this.$loop.schedule(this.CHANGE_FULL);
16707 this.session.$setFontMetrics(this.$fontMetrics);
16708 this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;
16709
16710 this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);
16711 this.onChangeNewLineMode();
16712 this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode);
16713 };
16714 this.updateLines = function(firstRow, lastRow, force) {
16715 if (lastRow === undefined)
16716 lastRow = Infinity;
16717
16718 if (!this.$changedLines) {
16719 this.$changedLines = {
16720 firstRow: firstRow,
16721 lastRow: lastRow
16722 };
16723 }
16724 else {
16725 if (this.$changedLines.firstRow > firstRow)
16726 this.$changedLines.firstRow = firstRow;
16727
16728 if (this.$changedLines.lastRow < lastRow)
16729 this.$changedLines.lastRow = lastRow;
16730 }
16731 if (this.$changedLines.lastRow < this.layerConfig.firstRow) {
16732 if (force)
16733 this.$changedLines.lastRow = this.layerConfig.lastRow;
16734 else
16735 return;
16736 }
16737 if (this.$changedLines.firstRow > this.layerConfig.lastRow)
16738 return;
16739 this.$loop.schedule(this.CHANGE_LINES);
16740 };
16741
16742 this.onChangeNewLineMode = function() {
16743 this.$loop.schedule(this.CHANGE_TEXT);
16744 this.$textLayer.$updateEolChar();
16745 this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR);
16746 };
16747
16748 this.onChangeTabSize = function() {
16749 this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);
16750 this.$textLayer.onChangeTabSize();
16751 };
16752 this.updateText = function() {
16753 this.$loop.schedule(this.CHANGE_TEXT);
16754 };
16755 this.updateFull = function(force) {
16756 if (force)
16757 this.$renderChanges(this.CHANGE_FULL, true);
16758 else
16759 this.$loop.schedule(this.CHANGE_FULL);
16760 };
16761 this.updateFontSize = function() {
16762 this.$textLayer.checkForSizeChanges();
16763 };
16764
16765 this.$changes = 0;
16766 this.$updateSizeAsync = function() {
16767 if (this.$loop.pending)
16768 this.$size.$dirty = true;
16769 else
16770 this.onResize();
16771 };
16772 this.onResize = function(force, gutterWidth, width, height) {
16773 if (this.resizing > 2)
16774 return;
16775 else if (this.resizing > 0)
16776 this.resizing++;
16777 else
16778 this.resizing = force ? 1 : 0;
16779 var el = this.container;
16780 if (!height)
16781 height = el.clientHeight || el.scrollHeight;
16782 if (!width)
16783 width = el.clientWidth || el.scrollWidth;
16784 var changes = this.$updateCachedSize(force, gutterWidth, width, height);
16785
16786
16787 if (!this.$size.scrollerHeight || (!width && !height))
16788 return this.resizing = 0;
16789
16790 if (force)
16791 this.$gutterLayer.$padding = null;
16792
16793 if (force)
16794 this.$renderChanges(changes | this.$changes, true);
16795 else
16796 this.$loop.schedule(changes | this.$changes);
16797
16798 if (this.resizing)
16799 this.resizing = 0;
16800 this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null;
16801 };
16802
16803 this.$updateCachedSize = function(force, gutterWidth, width, height) {
16804 height -= (this.$extraHeight || 0);
16805 var changes = 0;
16806 var size = this.$size;
16807 var oldSize = {
16808 width: size.width,
16809 height: size.height,
16810 scrollerHeight: size.scrollerHeight,
16811 scrollerWidth: size.scrollerWidth
16812 };
16813 if (height && (force || size.height != height)) {
16814 size.height = height;
16815 changes |= this.CHANGE_SIZE;
16816
16817 size.scrollerHeight = size.height;
16818 if (this.$horizScroll)
16819 size.scrollerHeight -= this.scrollBarH.getHeight();
16820 this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px";
16821
16822 changes = changes | this.CHANGE_SCROLL;
16823 }
16824
16825 if (width && (force || size.width != width)) {
16826 changes |= this.CHANGE_SIZE;
16827 size.width = width;
16828
16829 if (gutterWidth == null)
16830 gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
16831
16832 this.gutterWidth = gutterWidth;
16833
16834 this.scrollBarH.element.style.left =
16835 this.scroller.style.left = gutterWidth + "px";
16836 size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());
16837
16838 this.scrollBarH.element.style.right =
16839 this.scroller.style.right = this.scrollBarV.getWidth() + "px";
16840 this.scroller.style.bottom = this.scrollBarH.getHeight() + "px";
16841
16842 if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
16843 changes |= this.CHANGE_FULL;
16844 }
16845
16846 size.$dirty = !width || !height;
16847
16848 if (changes)
16849 this._signal("resize", oldSize);
16850
16851 return changes;
16852 };
16853
16854 this.onGutterResize = function() {
16855 var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
16856 if (gutterWidth != this.gutterWidth)
16857 this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
16858
16859 if (this.session.getUseWrapMode() && this.adjustWrapLimit()) {
16860 this.$loop.schedule(this.CHANGE_FULL);
16861 } else if (this.$size.$dirty) {
16862 this.$loop.schedule(this.CHANGE_FULL);
16863 } else {
16864 this.$computeLayerConfig();
16865 this.$loop.schedule(this.CHANGE_MARKER);
16866 }
16867 };
16868 this.adjustWrapLimit = function() {
16869 var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
16870 var limit = Math.floor(availableWidth / this.characterWidth);
16871 return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn);
16872 };
16873 this.setAnimatedScroll = function(shouldAnimate){
16874 this.setOption("animatedScroll", shouldAnimate);
16875 };
16876 this.getAnimatedScroll = function() {
16877 return this.$animatedScroll;
16878 };
16879 this.setShowInvisibles = function(showInvisibles) {
16880 this.setOption("showInvisibles", showInvisibles);
16881 this.session.$bidiHandler.setShowInvisibles(showInvisibles);
16882 };
16883 this.getShowInvisibles = function() {
16884 return this.getOption("showInvisibles");
16885 };
16886 this.getDisplayIndentGuides = function() {
16887 return this.getOption("displayIndentGuides");
16888 };
16889
16890 this.setDisplayIndentGuides = function(display) {
16891 this.setOption("displayIndentGuides", display);
16892 };
16893 this.setShowPrintMargin = function(showPrintMargin) {
16894 this.setOption("showPrintMargin", showPrintMargin);
16895 };
16896 this.getShowPrintMargin = function() {
16897 return this.getOption("showPrintMargin");
16898 };
16899 this.setPrintMarginColumn = function(showPrintMargin) {
16900 this.setOption("printMarginColumn", showPrintMargin);
16901 };
16902 this.getPrintMarginColumn = function() {
16903 return this.getOption("printMarginColumn");
16904 };
16905 this.getShowGutter = function(){
16906 return this.getOption("showGutter");
16907 };
16908 this.setShowGutter = function(show){
16909 return this.setOption("showGutter", show);
16910 };
16911
16912 this.getFadeFoldWidgets = function(){
16913 return this.getOption("fadeFoldWidgets");
16914 };
16915
16916 this.setFadeFoldWidgets = function(show) {
16917 this.setOption("fadeFoldWidgets", show);
16918 };
16919
16920 this.setHighlightGutterLine = function(shouldHighlight) {
16921 this.setOption("highlightGutterLine", shouldHighlight);
16922 };
16923
16924 this.getHighlightGutterLine = function() {
16925 return this.getOption("highlightGutterLine");
16926 };
16927
16928 this.$updateGutterLineHighlight = function() {
16929 var pos = this.$cursorLayer.$pixelPos;
16930 var height = this.layerConfig.lineHeight;
16931 if (this.session.getUseWrapMode()) {
16932 var cursor = this.session.selection.getCursor();
16933 cursor.column = 0;
16934 pos = this.$cursorLayer.getPixelPosition(cursor, true);
16935 height *= this.session.getRowLength(cursor.row);
16936 }
16937 this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px";
16938 this.$gutterLineHighlight.style.height = height + "px";
16939 };
16940
16941 this.$updatePrintMargin = function() {
16942 if (!this.$showPrintMargin && !this.$printMarginEl)
16943 return;
16944
16945 if (!this.$printMarginEl) {
16946 var containerEl = dom.createElement("div");
16947 containerEl.className = "ace_layer ace_print-margin-layer";
16948 this.$printMarginEl = dom.createElement("div");
16949 this.$printMarginEl.className = "ace_print-margin";
16950 containerEl.appendChild(this.$printMarginEl);
16951 this.content.insertBefore(containerEl, this.content.firstChild);
16952 }
16953
16954 var style = this.$printMarginEl.style;
16955 style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px";
16956 style.visibility = this.$showPrintMargin ? "visible" : "hidden";
16957
16958 if (this.session && this.session.$wrap == -1)
16959 this.adjustWrapLimit();
16960 };
16961 this.getContainerElement = function() {
16962 return this.container;
16963 };
16964 this.getMouseEventTarget = function() {
16965 return this.scroller;
16966 };
16967 this.getTextAreaContainer = function() {
16968 return this.container;
16969 };
16970 this.$moveTextAreaToCursor = function() {
16971 if (!this.$keepTextAreaAtCursor)
16972 return;
16973 var config = this.layerConfig;
16974 var posTop = this.$cursorLayer.$pixelPos.top;
16975 var posLeft = this.$cursorLayer.$pixelPos.left;
16976 posTop -= config.offset;
16977
16978 var style = this.textarea.style;
16979 var h = this.lineHeight;
16980 if (posTop < 0 || posTop > config.height - h) {
16981 style.top = style.left = "0";
16982 return;
16983 }
16984
16985 var w = this.characterWidth;
16986 if (this.$composition) {
16987 var val = this.textarea.value.replace(/^\x01+/, "");
16988 w *= (this.session.$getStringScreenWidth(val)[0]+2);
16989 h += 2;
16990 }
16991 posLeft -= this.scrollLeft;
16992 if (posLeft > this.$size.scrollerWidth - w)
16993 posLeft = this.$size.scrollerWidth - w;
16994
16995 posLeft += this.gutterWidth;
16996 style.height = h + "px";
16997 style.width = w + "px";
16998 style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + "px";
16999 style.top = Math.min(posTop, this.$size.height - h) + "px";
17000 };
17001 this.getFirstVisibleRow = function() {
17002 return this.layerConfig.firstRow;
17003 };
17004 this.getFirstFullyVisibleRow = function() {
17005 return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
17006 };
17007 this.getLastFullyVisibleRow = function() {
17008 var config = this.layerConfig;
17009 var lastRow = config.lastRow;
17010 var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight;
17011 if (top - this.session.getScrollTop() > config.height - config.lineHeight)
17012 return lastRow - 1;
17013 return lastRow;
17014 };
17015 this.getLastVisibleRow = function() {
17016 return this.layerConfig.lastRow;
17017 };
17018
17019 this.$padding = null;
17020 this.setPadding = function(padding) {
17021 this.$padding = padding;
17022 this.$textLayer.setPadding(padding);
17023 this.$cursorLayer.setPadding(padding);
17024 this.$markerFront.setPadding(padding);
17025 this.$markerBack.setPadding(padding);
17026 this.$loop.schedule(this.CHANGE_FULL);
17027 this.$updatePrintMargin();
17028 };
17029
17030 this.setScrollMargin = function(top, bottom, left, right) {
17031 var sm = this.scrollMargin;
17032 sm.top = top|0;
17033 sm.bottom = bottom|0;
17034 sm.right = right|0;
17035 sm.left = left|0;
17036 sm.v = sm.top + sm.bottom;
17037 sm.h = sm.left + sm.right;
17038 if (sm.top && this.scrollTop <= 0 && this.session)
17039 this.session.setScrollTop(-sm.top);
17040 this.updateFull();
17041 };
17042 this.getHScrollBarAlwaysVisible = function() {
17043 return this.$hScrollBarAlwaysVisible;
17044 };
17045 this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
17046 this.setOption("hScrollBarAlwaysVisible", alwaysVisible);
17047 };
17048 this.getVScrollBarAlwaysVisible = function() {
17049 return this.$vScrollBarAlwaysVisible;
17050 };
17051 this.setVScrollBarAlwaysVisible = function(alwaysVisible) {
17052 this.setOption("vScrollBarAlwaysVisible", alwaysVisible);
17053 };
17054
17055 this.$updateScrollBarV = function() {
17056 var scrollHeight = this.layerConfig.maxHeight;
17057 var scrollerHeight = this.$size.scrollerHeight;
17058 if (!this.$maxLines && this.$scrollPastEnd) {
17059 scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd;
17060 if (this.scrollTop > scrollHeight - scrollerHeight) {
17061 scrollHeight = this.scrollTop + scrollerHeight;
17062 this.scrollBarV.scrollTop = null;
17063 }
17064 }
17065 this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v);
17066 this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);
17067 };
17068 this.$updateScrollBarH = function() {
17069 this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);
17070 this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);
17071 };
17072
17073 this.$frozen = false;
17074 this.freeze = function() {
17075 this.$frozen = true;
17076 };
17077
17078 this.unfreeze = function() {
17079 this.$frozen = false;
17080 };
17081
17082 this.$renderChanges = function(changes, force) {
17083 if (this.$changes) {
17084 changes |= this.$changes;
17085 this.$changes = 0;
17086 }
17087 if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) {
17088 this.$changes |= changes;
17089 return;
17090 }
17091 if (this.$size.$dirty) {
17092 this.$changes |= changes;
17093 return this.onResize(true);
17094 }
17095 if (!this.lineHeight) {
17096 this.$textLayer.checkForSizeChanges();
17097 }
17098
17099 this._signal("beforeRender");
17100
17101 if (this.session && this.session.$bidiHandler)
17102 this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);
17103
17104 var config = this.layerConfig;
17105 if (changes & this.CHANGE_FULL ||
17106 changes & this.CHANGE_SIZE ||
17107 changes & this.CHANGE_TEXT ||
17108 changes & this.CHANGE_LINES ||
17109 changes & this.CHANGE_SCROLL ||
17110 changes & this.CHANGE_H_SCROLL
17111 ) {
17112 changes |= this.$computeLayerConfig();
17113 if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) {
17114 var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight;
17115 if (st > 0) {
17116 this.scrollTop = st;
17117 changes = changes | this.CHANGE_SCROLL;
17118 changes |= this.$computeLayerConfig();
17119 }
17120 }
17121 config = this.layerConfig;
17122 this.$updateScrollBarV();
17123 if (changes & this.CHANGE_H_SCROLL)
17124 this.$updateScrollBarH();
17125 this.$gutterLayer.element.style.marginTop = (-config.offset) + "px";
17126 this.content.style.marginTop = (-config.offset) + "px";
17127 this.content.style.width = config.width + 2 * this.$padding + "px";
17128 this.content.style.height = config.minHeight + "px";
17129 }
17130 if (changes & this.CHANGE_H_SCROLL) {
17131 this.content.style.marginLeft = -this.scrollLeft + "px";
17132 this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
17133 }
17134 if (changes & this.CHANGE_FULL) {
17135 this.$textLayer.update(config);
17136 if (this.$showGutter)
17137 this.$gutterLayer.update(config);
17138 this.$markerBack.update(config);
17139 this.$markerFront.update(config);
17140 this.$cursorLayer.update(config);
17141 this.$moveTextAreaToCursor();
17142 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17143 this._signal("afterRender");
17144 return;
17145 }
17146 if (changes & this.CHANGE_SCROLL) {
17147 if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
17148 this.$textLayer.update(config);
17149 else
17150 this.$textLayer.scrollLines(config);
17151
17152 if (this.$showGutter)
17153 this.$gutterLayer.update(config);
17154 this.$markerBack.update(config);
17155 this.$markerFront.update(config);
17156 this.$cursorLayer.update(config);
17157 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17158 this.$moveTextAreaToCursor();
17159 this._signal("afterRender");
17160 return;
17161 }
17162
17163 if (changes & this.CHANGE_TEXT) {
17164 this.$textLayer.update(config);
17165 if (this.$showGutter)
17166 this.$gutterLayer.update(config);
17167 }
17168 else if (changes & this.CHANGE_LINES) {
17169 if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
17170 this.$gutterLayer.update(config);
17171 }
17172 else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
17173 if (this.$showGutter)
17174 this.$gutterLayer.update(config);
17175 }
17176
17177 if (changes & this.CHANGE_CURSOR) {
17178 this.$cursorLayer.update(config);
17179 this.$moveTextAreaToCursor();
17180 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17181 }
17182
17183 if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
17184 this.$markerFront.update(config);
17185 }
17186
17187 if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
17188 this.$markerBack.update(config);
17189 }
17190
17191 this._signal("afterRender");
17192 };
17193
17194
17195 this.$autosize = function() {
17196 var height = this.session.getScreenLength() * this.lineHeight;
17197 var maxHeight = this.$maxLines * this.lineHeight;
17198 var desiredHeight = Math.min(maxHeight,
17199 Math.max((this.$minLines || 1) * this.lineHeight, height)
17200 ) + this.scrollMargin.v + (this.$extraHeight || 0);
17201 if (this.$horizScroll)
17202 desiredHeight += this.scrollBarH.getHeight();
17203 if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight)
17204 desiredHeight = this.$maxPixelHeight;
17205 var vScroll = height > maxHeight;
17206
17207 if (desiredHeight != this.desiredHeight ||
17208 this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {
17209 if (vScroll != this.$vScroll) {
17210 this.$vScroll = vScroll;
17211 this.scrollBarV.setVisible(vScroll);
17212 }
17213
17214 var w = this.container.clientWidth;
17215 this.container.style.height = desiredHeight + "px";
17216 this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);
17217 this.desiredHeight = desiredHeight;
17218
17219 this._signal("autosize");
17220 }
17221 };
17222
17223 this.$computeLayerConfig = function() {
17224 var session = this.session;
17225 var size = this.$size;
17226
17227 var hideScrollbars = size.height <= 2 * this.lineHeight;
17228 var screenLines = this.session.getScreenLength();
17229 var maxHeight = screenLines * this.lineHeight;
17230
17231 var longestLine = this.$getLongestLine();
17232
17233 var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||
17234 size.scrollerWidth - longestLine - 2 * this.$padding < 0);
17235
17236 var hScrollChanged = this.$horizScroll !== horizScroll;
17237 if (hScrollChanged) {
17238 this.$horizScroll = horizScroll;
17239 this.scrollBarH.setVisible(horizScroll);
17240 }
17241 var vScrollBefore = this.$vScroll; // autosize can change vscroll value in which case we need to update longestLine
17242 if (this.$maxLines && this.lineHeight > 1)
17243 this.$autosize();
17244
17245 var offset = this.scrollTop % this.lineHeight;
17246 var minHeight = size.scrollerHeight + this.lineHeight;
17247
17248 var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd
17249 ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd
17250 : 0;
17251 maxHeight += scrollPastEnd;
17252
17253 var sm = this.scrollMargin;
17254 this.session.setScrollTop(Math.max(-sm.top,
17255 Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom)));
17256
17257 this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft,
17258 longestLine + 2 * this.$padding - size.scrollerWidth + sm.right)));
17259
17260 var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||
17261 size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top);
17262 var vScrollChanged = vScrollBefore !== vScroll;
17263 if (vScrollChanged) {
17264 this.$vScroll = vScroll;
17265 this.scrollBarV.setVisible(vScroll);
17266 }
17267
17268 var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
17269 var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
17270 var lastRow = firstRow + lineCount;
17271 var firstRowScreen, firstRowHeight;
17272 var lineHeight = this.lineHeight;
17273 firstRow = session.screenToDocumentRow(firstRow, 0);
17274 var foldLine = session.getFoldLine(firstRow);
17275 if (foldLine) {
17276 firstRow = foldLine.start.row;
17277 }
17278
17279 firstRowScreen = session.documentToScreenRow(firstRow, 0);
17280 firstRowHeight = session.getRowLength(firstRow) * lineHeight;
17281
17282 lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);
17283 minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +
17284 firstRowHeight;
17285
17286 offset = this.scrollTop - firstRowScreen * lineHeight;
17287
17288 var changes = 0;
17289 if (this.layerConfig.width != longestLine)
17290 changes = this.CHANGE_H_SCROLL;
17291 if (hScrollChanged || vScrollChanged) {
17292 changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height);
17293 this._signal("scrollbarVisibilityChanged");
17294 if (vScrollChanged)
17295 longestLine = this.$getLongestLine();
17296 }
17297
17298 this.layerConfig = {
17299 width : longestLine,
17300 padding : this.$padding,
17301 firstRow : firstRow,
17302 firstRowScreen: firstRowScreen,
17303 lastRow : lastRow,
17304 lineHeight : lineHeight,
17305 characterWidth : this.characterWidth,
17306 minHeight : minHeight,
17307 maxHeight : maxHeight,
17308 offset : offset,
17309 gutterOffset : lineHeight ? Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)) : 0,
17310 height : this.$size.scrollerHeight
17311 };
17312
17313 return changes;
17314 };
17315
17316 this.$updateLines = function() {
17317 if (!this.$changedLines) return;
17318 var firstRow = this.$changedLines.firstRow;
17319 var lastRow = this.$changedLines.lastRow;
17320 this.$changedLines = null;
17321
17322 var layerConfig = this.layerConfig;
17323
17324 if (firstRow > layerConfig.lastRow + 1) { return; }
17325 if (lastRow < layerConfig.firstRow) { return; }
17326 if (lastRow === Infinity) {
17327 if (this.$showGutter)
17328 this.$gutterLayer.update(layerConfig);
17329 this.$textLayer.update(layerConfig);
17330 return;
17331 }
17332 this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
17333 return true;
17334 };
17335
17336 this.$getLongestLine = function() {
17337 var charCount = this.session.getScreenWidth();
17338 if (this.showInvisibles && !this.session.$useWrapMode)
17339 charCount += 1;
17340
17341 return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
17342 };
17343 this.updateFrontMarkers = function() {
17344 this.$markerFront.setMarkers(this.session.getMarkers(true));
17345 this.$loop.schedule(this.CHANGE_MARKER_FRONT);
17346 };
17347 this.updateBackMarkers = function() {
17348 this.$markerBack.setMarkers(this.session.getMarkers());
17349 this.$loop.schedule(this.CHANGE_MARKER_BACK);
17350 };
17351 this.addGutterDecoration = function(row, className){
17352 this.$gutterLayer.addGutterDecoration(row, className);
17353 };
17354 this.removeGutterDecoration = function(row, className){
17355 this.$gutterLayer.removeGutterDecoration(row, className);
17356 };
17357 this.updateBreakpoints = function(rows) {
17358 this.$loop.schedule(this.CHANGE_GUTTER);
17359 };
17360 this.setAnnotations = function(annotations) {
17361 this.$gutterLayer.setAnnotations(annotations);
17362 this.$loop.schedule(this.CHANGE_GUTTER);
17363 };
17364 this.updateCursor = function() {
17365 this.$loop.schedule(this.CHANGE_CURSOR);
17366 };
17367 this.hideCursor = function() {
17368 this.$cursorLayer.hideCursor();
17369 };
17370 this.showCursor = function() {
17371 this.$cursorLayer.showCursor();
17372 };
17373
17374 this.scrollSelectionIntoView = function(anchor, lead, offset) {
17375 this.scrollCursorIntoView(anchor, offset);
17376 this.scrollCursorIntoView(lead, offset);
17377 };
17378 this.scrollCursorIntoView = function(cursor, offset, $viewMargin) {
17379 if (this.$size.scrollerHeight === 0)
17380 return;
17381
17382 var pos = this.$cursorLayer.getPixelPosition(cursor);
17383
17384 var left = pos.left;
17385 var top = pos.top;
17386
17387 var topMargin = $viewMargin && $viewMargin.top || 0;
17388 var bottomMargin = $viewMargin && $viewMargin.bottom || 0;
17389
17390 var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
17391
17392 if (scrollTop + topMargin > top) {
17393 if (offset && scrollTop + topMargin > top + this.lineHeight)
17394 top -= offset * this.$size.scrollerHeight;
17395 if (top === 0)
17396 top = -this.scrollMargin.top;
17397 this.session.setScrollTop(top);
17398 } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) {
17399 if (offset && scrollTop + this.$size.scrollerHeight - bottomMargin < top - this.lineHeight)
17400 top += offset * this.$size.scrollerHeight;
17401 this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
17402 }
17403
17404 var scrollLeft = this.scrollLeft;
17405
17406 if (scrollLeft > left) {
17407 if (left < this.$padding + 2 * this.layerConfig.characterWidth)
17408 left = -this.scrollMargin.left;
17409 this.session.setScrollLeft(left);
17410 } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
17411 this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
17412 } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {
17413 this.session.setScrollLeft(0);
17414 }
17415 };
17416 this.getScrollTop = function() {
17417 return this.session.getScrollTop();
17418 };
17419 this.getScrollLeft = function() {
17420 return this.session.getScrollLeft();
17421 };
17422 this.getScrollTopRow = function() {
17423 return this.scrollTop / this.lineHeight;
17424 };
17425 this.getScrollBottomRow = function() {
17426 return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
17427 };
17428 this.scrollToRow = function(row) {
17429 this.session.setScrollTop(row * this.lineHeight);
17430 };
17431
17432 this.alignCursor = function(cursor, alignment) {
17433 if (typeof cursor == "number")
17434 cursor = {row: cursor, column: 0};
17435
17436 var pos = this.$cursorLayer.getPixelPosition(cursor);
17437 var h = this.$size.scrollerHeight - this.lineHeight;
17438 var offset = pos.top - h * (alignment || 0);
17439
17440 this.session.setScrollTop(offset);
17441 return offset;
17442 };
17443
17444 this.STEPS = 8;
17445 this.$calcSteps = function(fromValue, toValue){
17446 var i = 0;
17447 var l = this.STEPS;
17448 var steps = [];
17449
17450 var func = function(t, x_min, dx) {
17451 return dx * (Math.pow(t - 1, 3) + 1) + x_min;
17452 };
17453
17454 for (i = 0; i < l; ++i)
17455 steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
17456
17457 return steps;
17458 };
17459 this.scrollToLine = function(line, center, animate, callback) {
17460 var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
17461 var offset = pos.top;
17462 if (center)
17463 offset -= this.$size.scrollerHeight / 2;
17464
17465 var initialScroll = this.scrollTop;
17466 this.session.setScrollTop(offset);
17467 if (animate !== false)
17468 this.animateScrolling(initialScroll, callback);
17469 };
17470
17471 this.animateScrolling = function(fromValue, callback) {
17472 var toValue = this.scrollTop;
17473 if (!this.$animatedScroll)
17474 return;
17475 var _self = this;
17476
17477 if (fromValue == toValue)
17478 return;
17479
17480 if (this.$scrollAnimation) {
17481 var oldSteps = this.$scrollAnimation.steps;
17482 if (oldSteps.length) {
17483 fromValue = oldSteps[0];
17484 if (fromValue == toValue)
17485 return;
17486 }
17487 }
17488
17489 var steps = _self.$calcSteps(fromValue, toValue);
17490 this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};
17491
17492 clearInterval(this.$timer);
17493
17494 _self.session.setScrollTop(steps.shift());
17495 _self.session.$scrollTop = toValue;
17496 this.$timer = setInterval(function() {
17497 if (steps.length) {
17498 _self.session.setScrollTop(steps.shift());
17499 _self.session.$scrollTop = toValue;
17500 } else if (toValue != null) {
17501 _self.session.$scrollTop = -1;
17502 _self.session.setScrollTop(toValue);
17503 toValue = null;
17504 } else {
17505 _self.$timer = clearInterval(_self.$timer);
17506 _self.$scrollAnimation = null;
17507 callback && callback();
17508 }
17509 }, 10);
17510 };
17511 this.scrollToY = function(scrollTop) {
17512 if (this.scrollTop !== scrollTop) {
17513 this.$loop.schedule(this.CHANGE_SCROLL);
17514 this.scrollTop = scrollTop;
17515 }
17516 };
17517 this.scrollToX = function(scrollLeft) {
17518 if (this.scrollLeft !== scrollLeft)
17519 this.scrollLeft = scrollLeft;
17520 this.$loop.schedule(this.CHANGE_H_SCROLL);
17521 };
17522 this.scrollTo = function(x, y) {
17523 this.session.setScrollTop(y);
17524 this.session.setScrollLeft(y);
17525 };
17526 this.scrollBy = function(deltaX, deltaY) {
17527 deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
17528 deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
17529 };
17530 this.isScrollableBy = function(deltaX, deltaY) {
17531 if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)
17532 return true;
17533 if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight
17534 - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)
17535 return true;
17536 if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left)
17537 return true;
17538 if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth
17539 - this.layerConfig.width < -1 + this.scrollMargin.right)
17540 return true;
17541 };
17542
17543 this.pixelToScreenCoordinates = function(x, y) {
17544 var canvasPos = this.scroller.getBoundingClientRect();
17545
17546 var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;
17547 var offset = offsetX / this.characterWidth;
17548 var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
17549 var col = Math.round(offset);
17550
17551 return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX: offsetX};
17552 };
17553
17554 this.screenToTextCoordinates = function(x, y) {
17555 var canvasPos = this.scroller.getBoundingClientRect();
17556 var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;
17557
17558 var col = Math.round(offsetX / this.characterWidth);
17559
17560 var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight;
17561
17562 return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX);
17563 };
17564 this.textToScreenCoordinates = function(row, column) {
17565 var canvasPos = this.scroller.getBoundingClientRect();
17566 var pos = this.session.documentToScreenPosition(row, column);
17567
17568 var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row)
17569 ? this.session.$bidiHandler.getPosLeft(pos.column)
17570 : Math.round(pos.column * this.characterWidth));
17571
17572 var y = pos.row * this.lineHeight;
17573
17574 return {
17575 pageX: canvasPos.left + x - this.scrollLeft,
17576 pageY: canvasPos.top + y - this.scrollTop
17577 };
17578 };
17579 this.visualizeFocus = function() {
17580 dom.addCssClass(this.container, "ace_focus");
17581 };
17582 this.visualizeBlur = function() {
17583 dom.removeCssClass(this.container, "ace_focus");
17584 };
17585 this.showComposition = function(position) {
17586 if (!this.$composition)
17587 this.$composition = {
17588 keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
17589 cssText: this.textarea.style.cssText
17590 };
17591
17592 this.$keepTextAreaAtCursor = true;
17593 dom.addCssClass(this.textarea, "ace_composition");
17594 this.textarea.style.cssText = "";
17595 this.$moveTextAreaToCursor();
17596 };
17597 this.setCompositionText = function(text) {
17598 this.$moveTextAreaToCursor();
17599 };
17600 this.hideComposition = function() {
17601 if (!this.$composition)
17602 return;
17603
17604 dom.removeCssClass(this.textarea, "ace_composition");
17605 this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;
17606 this.textarea.style.cssText = this.$composition.cssText;
17607 this.$composition = null;
17608 };
17609 this.setTheme = function(theme, cb) {
17610 var _self = this;
17611 this.$themeId = theme;
17612 _self._dispatchEvent('themeChange',{theme:theme});
17613
17614 if (!theme || typeof theme == "string") {
17615 var moduleName = theme || this.$options.theme.initialValue;
17616 config.loadModule(["theme", moduleName], afterLoad);
17617 } else {
17618 afterLoad(theme);
17619 }
17620
17621 function afterLoad(module) {
17622 if (_self.$themeId != theme)
17623 return cb && cb();
17624 if (!module || !module.cssClass)
17625 throw new Error("couldn't load module " + theme + " or it didn't call define");
17626 dom.importCssString(
17627 module.cssText,
17628 module.cssClass,
17629 _self.container.ownerDocument
17630 );
17631
17632 if (_self.theme)
17633 dom.removeCssClass(_self.container, _self.theme.cssClass);
17634
17635 var padding = "padding" in module ? module.padding
17636 : "padding" in (_self.theme || {}) ? 4 : _self.$padding;
17637 if (_self.$padding && padding != _self.$padding)
17638 _self.setPadding(padding);
17639 _self.$theme = module.cssClass;
17640
17641 _self.theme = module;
17642 dom.addCssClass(_self.container, module.cssClass);
17643 dom.setCssClass(_self.container, "ace_dark", module.isDark);
17644 if (_self.$size) {
17645 _self.$size.width = 0;
17646 _self.$updateSizeAsync();
17647 }
17648
17649 _self._dispatchEvent('themeLoaded', {theme:module});
17650 cb && cb();
17651 }
17652 };
17653 this.getTheme = function() {
17654 return this.$themeId;
17655 };
17656 this.setStyle = function(style, include) {
17657 dom.setCssClass(this.container, style, include !== false);
17658 };
17659 this.unsetStyle = function(style) {
17660 dom.removeCssClass(this.container, style);
17661 };
17662
17663 this.setCursorStyle = function(style) {
17664 if (this.scroller.style.cursor != style)
17665 this.scroller.style.cursor = style;
17666 };
17667 this.setMouseCursor = function(cursorStyle) {
17668 this.scroller.style.cursor = cursorStyle;
17669 };
17670 this.destroy = function() {
17671 this.$textLayer.destroy();
17672 this.$cursorLayer.destroy();
17673 };
17674
17675}).call(VirtualRenderer.prototype);
17676
17677
17678config.defineOptions(VirtualRenderer.prototype, "renderer", {
17679 animatedScroll: {initialValue: false},
17680 showInvisibles: {
17681 set: function(value) {
17682 if (this.$textLayer.setShowInvisibles(value))
17683 this.$loop.schedule(this.CHANGE_TEXT);
17684 },
17685 initialValue: false
17686 },
17687 showPrintMargin: {
17688 set: function() { this.$updatePrintMargin(); },
17689 initialValue: true
17690 },
17691 printMarginColumn: {
17692 set: function() { this.$updatePrintMargin(); },
17693 initialValue: 80
17694 },
17695 printMargin: {
17696 set: function(val) {
17697 if (typeof val == "number")
17698 this.$printMarginColumn = val;
17699 this.$showPrintMargin = !!val;
17700 this.$updatePrintMargin();
17701 },
17702 get: function() {
17703 return this.$showPrintMargin && this.$printMarginColumn;
17704 }
17705 },
17706 showGutter: {
17707 set: function(show){
17708 this.$gutter.style.display = show ? "block" : "none";
17709 this.$loop.schedule(this.CHANGE_FULL);
17710 this.onGutterResize();
17711 },
17712 initialValue: true
17713 },
17714 fadeFoldWidgets: {
17715 set: function(show) {
17716 dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
17717 },
17718 initialValue: false
17719 },
17720 showFoldWidgets: {
17721 set: function(show) {this.$gutterLayer.setShowFoldWidgets(show);},
17722 initialValue: true
17723 },
17724 showLineNumbers: {
17725 set: function(show) {
17726 this.$gutterLayer.setShowLineNumbers(show);
17727 this.$loop.schedule(this.CHANGE_GUTTER);
17728 },
17729 initialValue: true
17730 },
17731 displayIndentGuides: {
17732 set: function(show) {
17733 if (this.$textLayer.setDisplayIndentGuides(show))
17734 this.$loop.schedule(this.CHANGE_TEXT);
17735 },
17736 initialValue: true
17737 },
17738 highlightGutterLine: {
17739 set: function(shouldHighlight) {
17740 if (!this.$gutterLineHighlight) {
17741 this.$gutterLineHighlight = dom.createElement("div");
17742 this.$gutterLineHighlight.className = "ace_gutter-active-line";
17743 this.$gutter.appendChild(this.$gutterLineHighlight);
17744 return;
17745 }
17746
17747 this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
17748 if (this.$cursorLayer.$pixelPos)
17749 this.$updateGutterLineHighlight();
17750 },
17751 initialValue: false,
17752 value: true
17753 },
17754 hScrollBarAlwaysVisible: {
17755 set: function(val) {
17756 if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)
17757 this.$loop.schedule(this.CHANGE_SCROLL);
17758 },
17759 initialValue: false
17760 },
17761 vScrollBarAlwaysVisible: {
17762 set: function(val) {
17763 if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)
17764 this.$loop.schedule(this.CHANGE_SCROLL);
17765 },
17766 initialValue: false
17767 },
17768 fontSize: {
17769 set: function(size) {
17770 if (typeof size == "number")
17771 size = size + "px";
17772 this.container.style.fontSize = size;
17773 this.updateFontSize();
17774 },
17775 initialValue: 12
17776 },
17777 fontFamily: {
17778 set: function(name) {
17779 this.container.style.fontFamily = name;
17780 this.updateFontSize();
17781 }
17782 },
17783 maxLines: {
17784 set: function(val) {
17785 this.updateFull();
17786 }
17787 },
17788 minLines: {
17789 set: function(val) {
17790 this.updateFull();
17791 }
17792 },
17793 maxPixelHeight: {
17794 set: function(val) {
17795 this.updateFull();
17796 },
17797 initialValue: 0
17798 },
17799 scrollPastEnd: {
17800 set: function(val) {
17801 val = +val || 0;
17802 if (this.$scrollPastEnd == val)
17803 return;
17804 this.$scrollPastEnd = val;
17805 this.$loop.schedule(this.CHANGE_SCROLL);
17806 },
17807 initialValue: 0,
17808 handlesSet: true
17809 },
17810 fixedWidthGutter: {
17811 set: function(val) {
17812 this.$gutterLayer.$fixedWidth = !!val;
17813 this.$loop.schedule(this.CHANGE_GUTTER);
17814 }
17815 },
17816 theme: {
17817 set: function(val) { this.setTheme(val); },
17818 get: function() { return this.$themeId || this.theme; },
17819 initialValue: "./theme/textmate",
17820 handlesSet: true
17821 }
17822});
17823
17824exports.VirtualRenderer = VirtualRenderer;
17825});
17826
17827ace.define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"], function(acequire, exports, module) {
17828
17829var oop = acequire("../lib/oop");
17830var net = acequire("../lib/net");
17831var EventEmitter = acequire("../lib/event_emitter").EventEmitter;
17832var config = acequire("../config");
17833
17834function $workerBlob(workerUrl, mod) {
17835 var script = mod.src;"importScripts('" + net.qualifyURL(workerUrl) + "');";
17836 try {
17837 return new Blob([script], {"type": "application/javascript"});
17838 } catch (e) { // Backwards-compatibility
17839 var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
17840 var blobBuilder = new BlobBuilder();
17841 blobBuilder.append(script);
17842 return blobBuilder.getBlob("application/javascript");
17843 }
17844}
17845
17846function createWorker(workerUrl, mod) {
17847 var blob = $workerBlob(workerUrl, mod);
17848 var URL = window.URL || window.webkitURL;
17849 var blobURL = URL.createObjectURL(blob);
17850 return new Worker(blobURL);
17851}
17852
17853var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl, importScripts) {
17854 this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
17855 this.changeListener = this.changeListener.bind(this);
17856 this.onMessage = this.onMessage.bind(this);
17857 if (acequire.nameToUrl && !acequire.toUrl)
17858 acequire.toUrl = acequire.nameToUrl;
17859
17860 if (config.get("packaged") || !acequire.toUrl) {
17861 workerUrl = workerUrl || config.moduleUrl(mod.id, "worker");
17862 } else {
17863 var normalizePath = this.$normalizePath;
17864 workerUrl = workerUrl || normalizePath(acequire.toUrl("ace/worker/worker.js", null, "_"));
17865
17866 var tlns = {};
17867 topLevelNamespaces.forEach(function(ns) {
17868 tlns[ns] = normalizePath(acequire.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, ""));
17869 });
17870 }
17871
17872 this.$worker = createWorker(workerUrl, mod);
17873 if (importScripts) {
17874 this.send("importScripts", importScripts);
17875 }
17876 this.$worker.postMessage({
17877 init : true,
17878 tlns : tlns,
17879 module : mod.id,
17880 classname : classname
17881 });
17882
17883 this.callbackId = 1;
17884 this.callbacks = {};
17885
17886 this.$worker.onmessage = this.onMessage;
17887};
17888
17889(function(){
17890
17891 oop.implement(this, EventEmitter);
17892
17893 this.onMessage = function(e) {
17894 var msg = e.data;
17895 switch (msg.type) {
17896 case "event":
17897 this._signal(msg.name, {data: msg.data});
17898 break;
17899 case "call":
17900 var callback = this.callbacks[msg.id];
17901 if (callback) {
17902 callback(msg.data);
17903 delete this.callbacks[msg.id];
17904 }
17905 break;
17906 case "error":
17907 this.reportError(msg.data);
17908 break;
17909 case "log":
17910 window.console && console.log && console.log.apply(console, msg.data);
17911 break;
17912 }
17913 };
17914
17915 this.reportError = function(err) {
17916 window.console && console.error && console.error(err);
17917 };
17918
17919 this.$normalizePath = function(path) {
17920 return net.qualifyURL(path);
17921 };
17922
17923 this.terminate = function() {
17924 this._signal("terminate", {});
17925 this.deltaQueue = null;
17926 this.$worker.terminate();
17927 this.$worker = null;
17928 if (this.$doc)
17929 this.$doc.off("change", this.changeListener);
17930 this.$doc = null;
17931 };
17932
17933 this.send = function(cmd, args) {
17934 this.$worker.postMessage({command: cmd, args: args});
17935 };
17936
17937 this.call = function(cmd, args, callback) {
17938 if (callback) {
17939 var id = this.callbackId++;
17940 this.callbacks[id] = callback;
17941 args.push(id);
17942 }
17943 this.send(cmd, args);
17944 };
17945
17946 this.emit = function(event, data) {
17947 try {
17948 this.$worker.postMessage({event: event, data: {data: data.data}});
17949 }
17950 catch(ex) {
17951 console.error(ex.stack);
17952 }
17953 };
17954
17955 this.attachToDocument = function(doc) {
17956 if (this.$doc)
17957 this.terminate();
17958
17959 this.$doc = doc;
17960 this.call("setValue", [doc.getValue()]);
17961 doc.on("change", this.changeListener);
17962 };
17963
17964 this.changeListener = function(delta) {
17965 if (!this.deltaQueue) {
17966 this.deltaQueue = [];
17967 setTimeout(this.$sendDeltaQueue, 0);
17968 }
17969 if (delta.action == "insert")
17970 this.deltaQueue.push(delta.start, delta.lines);
17971 else
17972 this.deltaQueue.push(delta.start, delta.end);
17973 };
17974
17975 this.$sendDeltaQueue = function() {
17976 var q = this.deltaQueue;
17977 if (!q) return;
17978 this.deltaQueue = null;
17979 if (q.length > 50 && q.length > this.$doc.getLength() >> 1) {
17980 this.call("setValue", [this.$doc.getValue()]);
17981 } else
17982 this.emit("change", {data: q});
17983 };
17984
17985}).call(WorkerClient.prototype);
17986
17987
17988var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
17989 this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
17990 this.changeListener = this.changeListener.bind(this);
17991 this.callbackId = 1;
17992 this.callbacks = {};
17993 this.messageBuffer = [];
17994
17995 var main = null;
17996 var emitSync = false;
17997 var sender = Object.create(EventEmitter);
17998 var _self = this;
17999
18000 this.$worker = {};
18001 this.$worker.terminate = function() {};
18002 this.$worker.postMessage = function(e) {
18003 _self.messageBuffer.push(e);
18004 if (main) {
18005 if (emitSync)
18006 setTimeout(processNext);
18007 else
18008 processNext();
18009 }
18010 };
18011 this.setEmitSync = function(val) { emitSync = val; };
18012
18013 var processNext = function() {
18014 var msg = _self.messageBuffer.shift();
18015 if (msg.command)
18016 main[msg.command].apply(main, msg.args);
18017 else if (msg.event)
18018 sender._signal(msg.event, msg.data);
18019 };
18020
18021 sender.postMessage = function(msg) {
18022 _self.onMessage({data: msg});
18023 };
18024 sender.callback = function(data, callbackId) {
18025 this.postMessage({type: "call", id: callbackId, data: data});
18026 };
18027 sender.emit = function(name, data) {
18028 this.postMessage({type: "event", name: name, data: data});
18029 };
18030
18031 config.loadModule(["worker", mod], function(Main) {
18032 main = new Main[classname](sender);
18033 while (_self.messageBuffer.length)
18034 processNext();
18035 });
18036};
18037
18038UIWorkerClient.prototype = WorkerClient.prototype;
18039
18040exports.UIWorkerClient = UIWorkerClient;
18041exports.WorkerClient = WorkerClient;
18042exports.createWorker = createWorker;
18043
18044
18045});
18046
18047ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"], function(acequire, exports, module) {
18048
18049var Range = acequire("./range").Range;
18050var EventEmitter = acequire("./lib/event_emitter").EventEmitter;
18051var oop = acequire("./lib/oop");
18052
18053var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
18054 var _self = this;
18055 this.length = length;
18056 this.session = session;
18057 this.doc = session.getDocument();
18058 this.mainClass = mainClass;
18059 this.othersClass = othersClass;
18060 this.$onUpdate = this.onUpdate.bind(this);
18061 this.doc.on("change", this.$onUpdate);
18062 this.$others = others;
18063
18064 this.$onCursorChange = function() {
18065 setTimeout(function() {
18066 _self.onCursorChange();
18067 });
18068 };
18069
18070 this.$pos = pos;
18071 var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
18072 this.$undoStackDepth = undoStack.length;
18073 this.setup();
18074
18075 session.selection.on("changeCursor", this.$onCursorChange);
18076};
18077
18078(function() {
18079
18080 oop.implement(this, EventEmitter);
18081 this.setup = function() {
18082 var _self = this;
18083 var doc = this.doc;
18084 var session = this.session;
18085
18086 this.selectionBefore = session.selection.toJSON();
18087 if (session.selection.inMultiSelectMode)
18088 session.selection.toSingleRange();
18089
18090 this.pos = doc.createAnchor(this.$pos.row, this.$pos.column);
18091 var pos = this.pos;
18092 pos.$insertRight = true;
18093 pos.detach();
18094 pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
18095 this.others = [];
18096 this.$others.forEach(function(other) {
18097 var anchor = doc.createAnchor(other.row, other.column);
18098 anchor.$insertRight = true;
18099 anchor.detach();
18100 _self.others.push(anchor);
18101 });
18102 session.setUndoSelect(false);
18103 };
18104 this.showOtherMarkers = function() {
18105 if (this.othersActive) return;
18106 var session = this.session;
18107 var _self = this;
18108 this.othersActive = true;
18109 this.others.forEach(function(anchor) {
18110 anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
18111 });
18112 };
18113 this.hideOtherMarkers = function() {
18114 if (!this.othersActive) return;
18115 this.othersActive = false;
18116 for (var i = 0; i < this.others.length; i++) {
18117 this.session.removeMarker(this.others[i].markerId);
18118 }
18119 };
18120 this.onUpdate = function(delta) {
18121 if (this.$updating)
18122 return this.updateAnchors(delta);
18123
18124 var range = delta;
18125 if (range.start.row !== range.end.row) return;
18126 if (range.start.row !== this.pos.row) return;
18127 this.$updating = true;
18128 var lengthDiff = delta.action === "insert" ? range.end.column - range.start.column : range.start.column - range.end.column;
18129 var inMainRange = range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1;
18130 var distanceFromStart = range.start.column - this.pos.column;
18131
18132 this.updateAnchors(delta);
18133
18134 if (inMainRange)
18135 this.length += lengthDiff;
18136
18137 if (inMainRange && !this.session.$fromUndo) {
18138 if (delta.action === 'insert') {
18139 for (var i = this.others.length - 1; i >= 0; i--) {
18140 var otherPos = this.others[i];
18141 var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
18142 this.doc.insertMergedLines(newPos, delta.lines);
18143 }
18144 } else if (delta.action === 'remove') {
18145 for (var i = this.others.length - 1; i >= 0; i--) {
18146 var otherPos = this.others[i];
18147 var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
18148 this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
18149 }
18150 }
18151 }
18152
18153 this.$updating = false;
18154 this.updateMarkers();
18155 };
18156
18157 this.updateAnchors = function(delta) {
18158 this.pos.onChange(delta);
18159 for (var i = this.others.length; i--;)
18160 this.others[i].onChange(delta);
18161 this.updateMarkers();
18162 };
18163
18164 this.updateMarkers = function() {
18165 if (this.$updating)
18166 return;
18167 var _self = this;
18168 var session = this.session;
18169 var updateMarker = function(pos, className) {
18170 session.removeMarker(pos.markerId);
18171 pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column+_self.length), className, null, false);
18172 };
18173 updateMarker(this.pos, this.mainClass);
18174 for (var i = this.others.length; i--;)
18175 updateMarker(this.others[i], this.othersClass);
18176 };
18177
18178 this.onCursorChange = function(event) {
18179 if (this.$updating || !this.session) return;
18180 var pos = this.session.selection.getCursor();
18181 if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
18182 this.showOtherMarkers();
18183 this._emit("cursorEnter", event);
18184 } else {
18185 this.hideOtherMarkers();
18186 this._emit("cursorLeave", event);
18187 }
18188 };
18189 this.detach = function() {
18190 this.session.removeMarker(this.pos && this.pos.markerId);
18191 this.hideOtherMarkers();
18192 this.doc.removeEventListener("change", this.$onUpdate);
18193 this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
18194 this.session.setUndoSelect(true);
18195 this.session = null;
18196 };
18197 this.cancel = function() {
18198 if (this.$undoStackDepth === -1)
18199 return;
18200 var undoManager = this.session.getUndoManager();
18201 var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
18202 for (var i = 0; i < undosRequired; i++) {
18203 undoManager.undo(true);
18204 }
18205 if (this.selectionBefore)
18206 this.session.selection.fromJSON(this.selectionBefore);
18207 };
18208}).call(PlaceHolder.prototype);
18209
18210
18211exports.PlaceHolder = PlaceHolder;
18212});
18213
18214ace.define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(acequire, exports, module) {
18215
18216var event = acequire("../lib/event");
18217var useragent = acequire("../lib/useragent");
18218function isSamePoint(p1, p2) {
18219 return p1.row == p2.row && p1.column == p2.column;
18220}
18221
18222function onMouseDown(e) {
18223 var ev = e.domEvent;
18224 var alt = ev.altKey;
18225 var shift = ev.shiftKey;
18226 var ctrl = ev.ctrlKey;
18227 var accel = e.getAccelKey();
18228 var button = e.getButton();
18229
18230 if (ctrl && useragent.isMac)
18231 button = ev.button;
18232
18233 if (e.editor.inMultiSelectMode && button == 2) {
18234 e.editor.textInput.onContextMenu(e.domEvent);
18235 return;
18236 }
18237
18238 if (!ctrl && !alt && !accel) {
18239 if (button === 0 && e.editor.inMultiSelectMode)
18240 e.editor.exitMultiSelectMode();
18241 return;
18242 }
18243
18244 if (button !== 0)
18245 return;
18246
18247 var editor = e.editor;
18248 var selection = editor.selection;
18249 var isMultiSelect = editor.inMultiSelectMode;
18250 var pos = e.getDocumentPosition();
18251 var cursor = selection.getCursor();
18252 var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
18253
18254 var mouseX = e.x, mouseY = e.y;
18255 var onMouseSelection = function(e) {
18256 mouseX = e.clientX;
18257 mouseY = e.clientY;
18258 };
18259
18260 var session = editor.session;
18261 var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
18262 var screenCursor = screenAnchor;
18263
18264 var selectionMode;
18265 if (editor.$mouseHandler.$enableJumpToDef) {
18266 if (ctrl && alt || accel && alt)
18267 selectionMode = shift ? "block" : "add";
18268 else if (alt && editor.$blockSelectEnabled)
18269 selectionMode = "block";
18270 } else {
18271 if (accel && !alt) {
18272 selectionMode = "add";
18273 if (!isMultiSelect && shift)
18274 return;
18275 } else if (alt && editor.$blockSelectEnabled) {
18276 selectionMode = "block";
18277 }
18278 }
18279
18280 if (selectionMode && useragent.isMac && ev.ctrlKey) {
18281 editor.$mouseHandler.cancelContextMenu();
18282 }
18283
18284 if (selectionMode == "add") {
18285 if (!isMultiSelect && inSelection)
18286 return; // dragging
18287
18288 if (!isMultiSelect) {
18289 var range = selection.toOrientedRange();
18290 editor.addSelectionMarker(range);
18291 }
18292
18293 var oldRange = selection.rangeList.rangeAtPoint(pos);
18294
18295
18296 editor.$blockScrolling++;
18297 editor.inVirtualSelectionMode = true;
18298
18299 if (shift) {
18300 oldRange = null;
18301 range = selection.ranges[0] || range;
18302 editor.removeSelectionMarker(range);
18303 }
18304 editor.once("mouseup", function() {
18305 var tmpSel = selection.toOrientedRange();
18306
18307 if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
18308 selection.substractPoint(tmpSel.cursor);
18309 else {
18310 if (shift) {
18311 selection.substractPoint(range.cursor);
18312 } else if (range) {
18313 editor.removeSelectionMarker(range);
18314 selection.addRange(range);
18315 }
18316 selection.addRange(tmpSel);
18317 }
18318 editor.$blockScrolling--;
18319 editor.inVirtualSelectionMode = false;
18320 });
18321
18322 } else if (selectionMode == "block") {
18323 e.stop();
18324 editor.inVirtualSelectionMode = true;
18325 var initialRange;
18326 var rectSel = [];
18327 var blockSelect = function() {
18328 var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
18329 var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX);
18330
18331 if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))
18332 return;
18333 screenCursor = newCursor;
18334
18335 editor.$blockScrolling++;
18336 editor.selection.moveToPosition(cursor);
18337 editor.renderer.scrollCursorIntoView();
18338
18339 editor.removeSelectionMarkers(rectSel);
18340 rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
18341 if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())
18342 rectSel[0] = editor.$mouseHandler.$clickSelection.clone();
18343 rectSel.forEach(editor.addSelectionMarker, editor);
18344 editor.updateSelectionMarkers();
18345 editor.$blockScrolling--;
18346 };
18347 editor.$blockScrolling++;
18348 if (isMultiSelect && !accel) {
18349 selection.toSingleRange();
18350 } else if (!isMultiSelect && accel) {
18351 initialRange = selection.toOrientedRange();
18352 editor.addSelectionMarker(initialRange);
18353 }
18354
18355 if (shift)
18356 screenAnchor = session.documentToScreenPosition(selection.lead);
18357 else
18358 selection.moveToPosition(pos);
18359 editor.$blockScrolling--;
18360
18361 screenCursor = {row: -1, column: -1};
18362
18363 var onMouseSelectionEnd = function(e) {
18364 clearInterval(timerId);
18365 editor.removeSelectionMarkers(rectSel);
18366 if (!rectSel.length)
18367 rectSel = [selection.toOrientedRange()];
18368 editor.$blockScrolling++;
18369 if (initialRange) {
18370 editor.removeSelectionMarker(initialRange);
18371 selection.toSingleRange(initialRange);
18372 }
18373 for (var i = 0; i < rectSel.length; i++)
18374 selection.addRange(rectSel[i]);
18375 editor.inVirtualSelectionMode = false;
18376 editor.$mouseHandler.$clickSelection = null;
18377 editor.$blockScrolling--;
18378 };
18379
18380 var onSelectionInterval = blockSelect;
18381
18382 event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
18383 var timerId = setInterval(function() {onSelectionInterval();}, 20);
18384
18385 return e.preventDefault();
18386 }
18387}
18388
18389
18390exports.onMouseDown = onMouseDown;
18391
18392});
18393
18394ace.define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"], function(acequire, exports, module) {
18395exports.defaultCommands = [{
18396 name: "addCursorAbove",
18397 exec: function(editor) { editor.selectMoreLines(-1); },
18398 bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
18399 scrollIntoView: "cursor",
18400 readOnly: true
18401}, {
18402 name: "addCursorBelow",
18403 exec: function(editor) { editor.selectMoreLines(1); },
18404 bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
18405 scrollIntoView: "cursor",
18406 readOnly: true
18407}, {
18408 name: "addCursorAboveSkipCurrent",
18409 exec: function(editor) { editor.selectMoreLines(-1, true); },
18410 bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
18411 scrollIntoView: "cursor",
18412 readOnly: true
18413}, {
18414 name: "addCursorBelowSkipCurrent",
18415 exec: function(editor) { editor.selectMoreLines(1, true); },
18416 bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
18417 scrollIntoView: "cursor",
18418 readOnly: true
18419}, {
18420 name: "selectMoreBefore",
18421 exec: function(editor) { editor.selectMore(-1); },
18422 bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
18423 scrollIntoView: "cursor",
18424 readOnly: true
18425}, {
18426 name: "selectMoreAfter",
18427 exec: function(editor) { editor.selectMore(1); },
18428 bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
18429 scrollIntoView: "cursor",
18430 readOnly: true
18431}, {
18432 name: "selectNextBefore",
18433 exec: function(editor) { editor.selectMore(-1, true); },
18434 bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
18435 scrollIntoView: "cursor",
18436 readOnly: true
18437}, {
18438 name: "selectNextAfter",
18439 exec: function(editor) { editor.selectMore(1, true); },
18440 bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
18441 scrollIntoView: "cursor",
18442 readOnly: true
18443}, {
18444 name: "splitIntoLines",
18445 exec: function(editor) { editor.multiSelect.splitIntoLines(); },
18446 bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
18447 readOnly: true
18448}, {
18449 name: "alignCursors",
18450 exec: function(editor) { editor.alignCursors(); },
18451 bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"},
18452 scrollIntoView: "cursor"
18453}, {
18454 name: "findAll",
18455 exec: function(editor) { editor.findAll(); },
18456 bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"},
18457 scrollIntoView: "cursor",
18458 readOnly: true
18459}];
18460exports.multiSelectCommands = [{
18461 name: "singleSelection",
18462 bindKey: "esc",
18463 exec: function(editor) { editor.exitMultiSelectMode(); },
18464 scrollIntoView: "cursor",
18465 readOnly: true,
18466 isAvailable: function(editor) {return editor && editor.inMultiSelectMode;}
18467}];
18468
18469var HashHandler = acequire("../keyboard/hash_handler").HashHandler;
18470exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
18471
18472});
18473
18474ace.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) {
18475
18476var RangeList = acequire("./range_list").RangeList;
18477var Range = acequire("./range").Range;
18478var Selection = acequire("./selection").Selection;
18479var onMouseDown = acequire("./mouse/multi_select_handler").onMouseDown;
18480var event = acequire("./lib/event");
18481var lang = acequire("./lib/lang");
18482var commands = acequire("./commands/multi_select_commands");
18483exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
18484var Search = acequire("./search").Search;
18485var search = new Search();
18486
18487function find(session, needle, dir) {
18488 search.$options.wrap = true;
18489 search.$options.needle = needle;
18490 search.$options.backwards = dir == -1;
18491 return search.find(session);
18492}
18493var EditSession = acequire("./edit_session").EditSession;
18494(function() {
18495 this.getSelectionMarkers = function() {
18496 return this.$selectionMarkers;
18497 };
18498}).call(EditSession.prototype);
18499(function() {
18500 this.ranges = null;
18501 this.rangeList = null;
18502 this.addRange = function(range, $blockChangeEvents) {
18503 if (!range)
18504 return;
18505
18506 if (!this.inMultiSelectMode && this.rangeCount === 0) {
18507 var oldRange = this.toOrientedRange();
18508 this.rangeList.add(oldRange);
18509 this.rangeList.add(range);
18510 if (this.rangeList.ranges.length != 2) {
18511 this.rangeList.removeAll();
18512 return $blockChangeEvents || this.fromOrientedRange(range);
18513 }
18514 this.rangeList.removeAll();
18515 this.rangeList.add(oldRange);
18516 this.$onAddRange(oldRange);
18517 }
18518
18519 if (!range.cursor)
18520 range.cursor = range.end;
18521
18522 var removed = this.rangeList.add(range);
18523
18524 this.$onAddRange(range);
18525
18526 if (removed.length)
18527 this.$onRemoveRange(removed);
18528
18529 if (this.rangeCount > 1 && !this.inMultiSelectMode) {
18530 this._signal("multiSelect");
18531 this.inMultiSelectMode = true;
18532 this.session.$undoSelect = false;
18533 this.rangeList.attach(this.session);
18534 }
18535
18536 return $blockChangeEvents || this.fromOrientedRange(range);
18537 };
18538
18539 this.toSingleRange = function(range) {
18540 range = range || this.ranges[0];
18541 var removed = this.rangeList.removeAll();
18542 if (removed.length)
18543 this.$onRemoveRange(removed);
18544
18545 range && this.fromOrientedRange(range);
18546 };
18547 this.substractPoint = function(pos) {
18548 var removed = this.rangeList.substractPoint(pos);
18549 if (removed) {
18550 this.$onRemoveRange(removed);
18551 return removed[0];
18552 }
18553 };
18554 this.mergeOverlappingRanges = function() {
18555 var removed = this.rangeList.merge();
18556 if (removed.length)
18557 this.$onRemoveRange(removed);
18558 else if(this.ranges[0])
18559 this.fromOrientedRange(this.ranges[0]);
18560 };
18561
18562 this.$onAddRange = function(range) {
18563 this.rangeCount = this.rangeList.ranges.length;
18564 this.ranges.unshift(range);
18565 this._signal("addRange", {range: range});
18566 };
18567
18568 this.$onRemoveRange = function(removed) {
18569 this.rangeCount = this.rangeList.ranges.length;
18570 if (this.rangeCount == 1 && this.inMultiSelectMode) {
18571 var lastRange = this.rangeList.ranges.pop();
18572 removed.push(lastRange);
18573 this.rangeCount = 0;
18574 }
18575
18576 for (var i = removed.length; i--; ) {
18577 var index = this.ranges.indexOf(removed[i]);
18578 this.ranges.splice(index, 1);
18579 }
18580
18581 this._signal("removeRange", {ranges: removed});
18582
18583 if (this.rangeCount === 0 && this.inMultiSelectMode) {
18584 this.inMultiSelectMode = false;
18585 this._signal("singleSelect");
18586 this.session.$undoSelect = true;
18587 this.rangeList.detach(this.session);
18588 }
18589
18590 lastRange = lastRange || this.ranges[0];
18591 if (lastRange && !lastRange.isEqual(this.getRange()))
18592 this.fromOrientedRange(lastRange);
18593 };
18594 this.$initRangeList = function() {
18595 if (this.rangeList)
18596 return;
18597
18598 this.rangeList = new RangeList();
18599 this.ranges = [];
18600 this.rangeCount = 0;
18601 };
18602 this.getAllRanges = function() {
18603 return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];
18604 };
18605
18606 this.splitIntoLines = function () {
18607 if (this.rangeCount > 1) {
18608 var ranges = this.rangeList.ranges;
18609 var lastRange = ranges[ranges.length - 1];
18610 var range = Range.fromPoints(ranges[0].start, lastRange.end);
18611
18612 this.toSingleRange();
18613 this.setSelectionRange(range, lastRange.cursor == lastRange.start);
18614 } else {
18615 var range = this.getRange();
18616 var isBackwards = this.isBackwards();
18617 var startRow = range.start.row;
18618 var endRow = range.end.row;
18619 if (startRow == endRow) {
18620 if (isBackwards)
18621 var start = range.end, end = range.start;
18622 else
18623 var start = range.start, end = range.end;
18624
18625 this.addRange(Range.fromPoints(end, end));
18626 this.addRange(Range.fromPoints(start, start));
18627 return;
18628 }
18629
18630 var rectSel = [];
18631 var r = this.getLineRange(startRow, true);
18632 r.start.column = range.start.column;
18633 rectSel.push(r);
18634
18635 for (var i = startRow + 1; i < endRow; i++)
18636 rectSel.push(this.getLineRange(i, true));
18637
18638 r = this.getLineRange(endRow, true);
18639 r.end.column = range.end.column;
18640 rectSel.push(r);
18641
18642 rectSel.forEach(this.addRange, this);
18643 }
18644 };
18645 this.toggleBlockSelection = function () {
18646 if (this.rangeCount > 1) {
18647 var ranges = this.rangeList.ranges;
18648 var lastRange = ranges[ranges.length - 1];
18649 var range = Range.fromPoints(ranges[0].start, lastRange.end);
18650
18651 this.toSingleRange();
18652 this.setSelectionRange(range, lastRange.cursor == lastRange.start);
18653 } else {
18654 var cursor = this.session.documentToScreenPosition(this.selectionLead);
18655 var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
18656
18657 var rectSel = this.rectangularRangeBlock(cursor, anchor);
18658 rectSel.forEach(this.addRange, this);
18659 }
18660 };
18661 this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
18662 var rectSel = [];
18663
18664 var xBackwards = screenCursor.column < screenAnchor.column;
18665 if (xBackwards) {
18666 var startColumn = screenCursor.column;
18667 var endColumn = screenAnchor.column;
18668 var startOffsetX = screenCursor.offsetX;
18669 var endOffsetX = screenAnchor.offsetX;
18670 } else {
18671 var startColumn = screenAnchor.column;
18672 var endColumn = screenCursor.column;
18673 var startOffsetX = screenAnchor.offsetX;
18674 var endOffsetX = screenCursor.offsetX;
18675 }
18676
18677 var yBackwards = screenCursor.row < screenAnchor.row;
18678 if (yBackwards) {
18679 var startRow = screenCursor.row;
18680 var endRow = screenAnchor.row;
18681 } else {
18682 var startRow = screenAnchor.row;
18683 var endRow = screenCursor.row;
18684 }
18685
18686 if (startColumn < 0)
18687 startColumn = 0;
18688 if (startRow < 0)
18689 startRow = 0;
18690
18691 if (startRow == endRow)
18692 includeEmptyLines = true;
18693
18694 for (var row = startRow; row <= endRow; row++) {
18695 var range = Range.fromPoints(
18696 this.session.screenToDocumentPosition(row, startColumn, startOffsetX),
18697 this.session.screenToDocumentPosition(row, endColumn, endOffsetX)
18698 );
18699 if (range.isEmpty()) {
18700 if (docEnd && isSamePoint(range.end, docEnd))
18701 break;
18702 var docEnd = range.end;
18703 }
18704 range.cursor = xBackwards ? range.start : range.end;
18705 rectSel.push(range);
18706 }
18707
18708 if (yBackwards)
18709 rectSel.reverse();
18710
18711 if (!includeEmptyLines) {
18712 var end = rectSel.length - 1;
18713 while (rectSel[end].isEmpty() && end > 0)
18714 end--;
18715 if (end > 0) {
18716 var start = 0;
18717 while (rectSel[start].isEmpty())
18718 start++;
18719 }
18720 for (var i = end; i >= start; i--) {
18721 if (rectSel[i].isEmpty())
18722 rectSel.splice(i, 1);
18723 }
18724 }
18725
18726 return rectSel;
18727 };
18728}).call(Selection.prototype);
18729var Editor = acequire("./editor").Editor;
18730(function() {
18731 this.updateSelectionMarkers = function() {
18732 this.renderer.updateCursor();
18733 this.renderer.updateBackMarkers();
18734 };
18735 this.addSelectionMarker = function(orientedRange) {
18736 if (!orientedRange.cursor)
18737 orientedRange.cursor = orientedRange.end;
18738
18739 var style = this.getSelectionStyle();
18740 orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
18741
18742 this.session.$selectionMarkers.push(orientedRange);
18743 this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
18744 return orientedRange;
18745 };
18746 this.removeSelectionMarker = function(range) {
18747 if (!range.marker)
18748 return;
18749 this.session.removeMarker(range.marker);
18750 var index = this.session.$selectionMarkers.indexOf(range);
18751 if (index != -1)
18752 this.session.$selectionMarkers.splice(index, 1);
18753 this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
18754 };
18755
18756 this.removeSelectionMarkers = function(ranges) {
18757 var markerList = this.session.$selectionMarkers;
18758 for (var i = ranges.length; i--; ) {
18759 var range = ranges[i];
18760 if (!range.marker)
18761 continue;
18762 this.session.removeMarker(range.marker);
18763 var index = markerList.indexOf(range);
18764 if (index != -1)
18765 markerList.splice(index, 1);
18766 }
18767 this.session.selectionMarkerCount = markerList.length;
18768 };
18769
18770 this.$onAddRange = function(e) {
18771 this.addSelectionMarker(e.range);
18772 this.renderer.updateCursor();
18773 this.renderer.updateBackMarkers();
18774 };
18775
18776 this.$onRemoveRange = function(e) {
18777 this.removeSelectionMarkers(e.ranges);
18778 this.renderer.updateCursor();
18779 this.renderer.updateBackMarkers();
18780 };
18781
18782 this.$onMultiSelect = function(e) {
18783 if (this.inMultiSelectMode)
18784 return;
18785 this.inMultiSelectMode = true;
18786
18787 this.setStyle("ace_multiselect");
18788 this.keyBinding.addKeyboardHandler(commands.keyboardHandler);
18789 this.commands.setDefaultHandler("exec", this.$onMultiSelectExec);
18790
18791 this.renderer.updateCursor();
18792 this.renderer.updateBackMarkers();
18793 };
18794
18795 this.$onSingleSelect = function(e) {
18796 if (this.session.multiSelect.inVirtualMode)
18797 return;
18798 this.inMultiSelectMode = false;
18799
18800 this.unsetStyle("ace_multiselect");
18801 this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);
18802
18803 this.commands.removeDefaultHandler("exec", this.$onMultiSelectExec);
18804 this.renderer.updateCursor();
18805 this.renderer.updateBackMarkers();
18806 this._emit("changeSelection");
18807 };
18808
18809 this.$onMultiSelectExec = function(e) {
18810 var command = e.command;
18811 var editor = e.editor;
18812 if (!editor.multiSelect)
18813 return;
18814 if (!command.multiSelectAction) {
18815 var result = command.exec(editor, e.args || {});
18816 editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
18817 editor.multiSelect.mergeOverlappingRanges();
18818 } else if (command.multiSelectAction == "forEach") {
18819 result = editor.forEachSelection(command, e.args);
18820 } else if (command.multiSelectAction == "forEachLine") {
18821 result = editor.forEachSelection(command, e.args, true);
18822 } else if (command.multiSelectAction == "single") {
18823 editor.exitMultiSelectMode();
18824 result = command.exec(editor, e.args || {});
18825 } else {
18826 result = command.multiSelectAction(editor, e.args || {});
18827 }
18828 return result;
18829 };
18830 this.forEachSelection = function(cmd, args, options) {
18831 if (this.inVirtualSelectionMode)
18832 return;
18833 var keepOrder = options && options.keepOrder;
18834 var $byLines = options == true || options && options.$byLines;
18835 var session = this.session;
18836 var selection = this.selection;
18837 var rangeList = selection.rangeList;
18838 var ranges = (keepOrder ? selection : rangeList).ranges;
18839 var result;
18840
18841 if (!ranges.length)
18842 return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
18843
18844 var reg = selection._eventRegistry;
18845 selection._eventRegistry = {};
18846
18847 var tmpSel = new Selection(session);
18848 this.inVirtualSelectionMode = true;
18849 for (var i = ranges.length; i--;) {
18850 if ($byLines) {
18851 while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row)
18852 i--;
18853 }
18854 tmpSel.fromOrientedRange(ranges[i]);
18855 tmpSel.index = i;
18856 this.selection = session.selection = tmpSel;
18857 var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
18858 if (!result && cmdResult !== undefined)
18859 result = cmdResult;
18860 tmpSel.toOrientedRange(ranges[i]);
18861 }
18862 tmpSel.detach();
18863
18864 this.selection = session.selection = selection;
18865 this.inVirtualSelectionMode = false;
18866 selection._eventRegistry = reg;
18867 selection.mergeOverlappingRanges();
18868
18869 var anim = this.renderer.$scrollAnimation;
18870 this.onCursorChange();
18871 this.onSelectionChange();
18872 if (anim && anim.from == anim.to)
18873 this.renderer.animateScrolling(anim.from);
18874
18875 return result;
18876 };
18877 this.exitMultiSelectMode = function() {
18878 if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
18879 return;
18880 this.multiSelect.toSingleRange();
18881 };
18882
18883 this.getSelectedText = function() {
18884 var text = "";
18885 if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
18886 var ranges = this.multiSelect.rangeList.ranges;
18887 var buf = [];
18888 for (var i = 0; i < ranges.length; i++) {
18889 buf.push(this.session.getTextRange(ranges[i]));
18890 }
18891 var nl = this.session.getDocument().getNewLineCharacter();
18892 text = buf.join(nl);
18893 if (text.length == (buf.length - 1) * nl.length)
18894 text = "";
18895 } else if (!this.selection.isEmpty()) {
18896 text = this.session.getTextRange(this.getSelectionRange());
18897 }
18898 return text;
18899 };
18900
18901 this.$checkMultiselectChange = function(e, anchor) {
18902 if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
18903 var range = this.multiSelect.ranges[0];
18904 if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)
18905 return;
18906 var pos = anchor == this.multiSelect.anchor
18907 ? range.cursor == range.start ? range.end : range.start
18908 : range.cursor;
18909 if (pos.row != anchor.row
18910 || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column)
18911 this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());
18912 }
18913 };
18914 this.findAll = function(needle, options, additive) {
18915 options = options || {};
18916 options.needle = needle || options.needle;
18917 if (options.needle == undefined) {
18918 var range = this.selection.isEmpty()
18919 ? this.selection.getWordRange()
18920 : this.selection.getRange();
18921 options.needle = this.session.getTextRange(range);
18922 }
18923 this.$search.set(options);
18924
18925 var ranges = this.$search.findAll(this.session);
18926 if (!ranges.length)
18927 return 0;
18928
18929 this.$blockScrolling += 1;
18930 var selection = this.multiSelect;
18931
18932 if (!additive)
18933 selection.toSingleRange(ranges[0]);
18934
18935 for (var i = ranges.length; i--; )
18936 selection.addRange(ranges[i], true);
18937 if (range && selection.rangeList.rangeAtPoint(range.start))
18938 selection.addRange(range, true);
18939
18940 this.$blockScrolling -= 1;
18941
18942 return ranges.length;
18943 };
18944 this.selectMoreLines = function(dir, skip) {
18945 var range = this.selection.toOrientedRange();
18946 var isBackwards = range.cursor == range.end;
18947
18948 var screenLead = this.session.documentToScreenPosition(range.cursor);
18949 if (this.selection.$desiredColumn)
18950 screenLead.column = this.selection.$desiredColumn;
18951
18952 var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
18953
18954 if (!range.isEmpty()) {
18955 var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
18956 var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
18957 } else {
18958 var anchor = lead;
18959 }
18960
18961 if (isBackwards) {
18962 var newRange = Range.fromPoints(lead, anchor);
18963 newRange.cursor = newRange.start;
18964 } else {
18965 var newRange = Range.fromPoints(anchor, lead);
18966 newRange.cursor = newRange.end;
18967 }
18968
18969 newRange.desiredColumn = screenLead.column;
18970 if (!this.selection.inMultiSelectMode) {
18971 this.selection.addRange(range);
18972 } else {
18973 if (skip)
18974 var toRemove = range.cursor;
18975 }
18976
18977 this.selection.addRange(newRange);
18978 if (toRemove)
18979 this.selection.substractPoint(toRemove);
18980 };
18981 this.transposeSelections = function(dir) {
18982 var session = this.session;
18983 var sel = session.multiSelect;
18984 var all = sel.ranges;
18985
18986 for (var i = all.length; i--; ) {
18987 var range = all[i];
18988 if (range.isEmpty()) {
18989 var tmp = session.getWordRange(range.start.row, range.start.column);
18990 range.start.row = tmp.start.row;
18991 range.start.column = tmp.start.column;
18992 range.end.row = tmp.end.row;
18993 range.end.column = tmp.end.column;
18994 }
18995 }
18996 sel.mergeOverlappingRanges();
18997
18998 var words = [];
18999 for (var i = all.length; i--; ) {
19000 var range = all[i];
19001 words.unshift(session.getTextRange(range));
19002 }
19003
19004 if (dir < 0)
19005 words.unshift(words.pop());
19006 else
19007 words.push(words.shift());
19008
19009 for (var i = all.length; i--; ) {
19010 var range = all[i];
19011 var tmp = range.clone();
19012 session.replace(range, words[i]);
19013 range.start.row = tmp.start.row;
19014 range.start.column = tmp.start.column;
19015 }
19016 };
19017 this.selectMore = function(dir, skip, stopAtFirst) {
19018 var session = this.session;
19019 var sel = session.multiSelect;
19020
19021 var range = sel.toOrientedRange();
19022 if (range.isEmpty()) {
19023 range = session.getWordRange(range.start.row, range.start.column);
19024 range.cursor = dir == -1 ? range.start : range.end;
19025 this.multiSelect.addRange(range);
19026 if (stopAtFirst)
19027 return;
19028 }
19029 var needle = session.getTextRange(range);
19030
19031 var newRange = find(session, needle, dir);
19032 if (newRange) {
19033 newRange.cursor = dir == -1 ? newRange.start : newRange.end;
19034 this.$blockScrolling += 1;
19035 this.session.unfold(newRange);
19036 this.multiSelect.addRange(newRange);
19037 this.$blockScrolling -= 1;
19038 this.renderer.scrollCursorIntoView(null, 0.5);
19039 }
19040 if (skip)
19041 this.multiSelect.substractPoint(range.cursor);
19042 };
19043 this.alignCursors = function() {
19044 var session = this.session;
19045 var sel = session.multiSelect;
19046 var ranges = sel.ranges;
19047 var row = -1;
19048 var sameRowRanges = ranges.filter(function(r) {
19049 if (r.cursor.row == row)
19050 return true;
19051 row = r.cursor.row;
19052 });
19053
19054 if (!ranges.length || sameRowRanges.length == ranges.length - 1) {
19055 var range = this.selection.getRange();
19056 var fr = range.start.row, lr = range.end.row;
19057 var guessRange = fr == lr;
19058 if (guessRange) {
19059 var max = this.session.getLength();
19060 var line;
19061 do {
19062 line = this.session.getLine(lr);
19063 } while (/[=:]/.test(line) && ++lr < max);
19064 do {
19065 line = this.session.getLine(fr);
19066 } while (/[=:]/.test(line) && --fr > 0);
19067
19068 if (fr < 0) fr = 0;
19069 if (lr >= max) lr = max - 1;
19070 }
19071 var lines = this.session.removeFullLines(fr, lr);
19072 lines = this.$reAlignText(lines, guessRange);
19073 this.session.insert({row: fr, column: 0}, lines.join("\n") + "\n");
19074 if (!guessRange) {
19075 range.start.column = 0;
19076 range.end.column = lines[lines.length - 1].length;
19077 }
19078 this.selection.setRange(range);
19079 } else {
19080 sameRowRanges.forEach(function(r) {
19081 sel.substractPoint(r.cursor);
19082 });
19083
19084 var maxCol = 0;
19085 var minSpace = Infinity;
19086 var spaceOffsets = ranges.map(function(r) {
19087 var p = r.cursor;
19088 var line = session.getLine(p.row);
19089 var spaceOffset = line.substr(p.column).search(/\S/g);
19090 if (spaceOffset == -1)
19091 spaceOffset = 0;
19092
19093 if (p.column > maxCol)
19094 maxCol = p.column;
19095 if (spaceOffset < minSpace)
19096 minSpace = spaceOffset;
19097 return spaceOffset;
19098 });
19099 ranges.forEach(function(r, i) {
19100 var p = r.cursor;
19101 var l = maxCol - p.column;
19102 var d = spaceOffsets[i] - minSpace;
19103 if (l > d)
19104 session.insert(p, lang.stringRepeat(" ", l - d));
19105 else
19106 session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
19107
19108 r.start.column = r.end.column = maxCol;
19109 r.start.row = r.end.row = p.row;
19110 r.cursor = r.end;
19111 });
19112 sel.fromOrientedRange(ranges[0]);
19113 this.renderer.updateCursor();
19114 this.renderer.updateBackMarkers();
19115 }
19116 };
19117
19118 this.$reAlignText = function(lines, forceLeft) {
19119 var isLeftAligned = true, isRightAligned = true;
19120 var startW, textW, endW;
19121
19122 return lines.map(function(line) {
19123 var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
19124 if (!m)
19125 return [line];
19126
19127 if (startW == null) {
19128 startW = m[1].length;
19129 textW = m[2].length;
19130 endW = m[3].length;
19131 return m;
19132 }
19133
19134 if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
19135 isRightAligned = false;
19136 if (startW != m[1].length)
19137 isLeftAligned = false;
19138
19139 if (startW > m[1].length)
19140 startW = m[1].length;
19141 if (textW < m[2].length)
19142 textW = m[2].length;
19143 if (endW > m[3].length)
19144 endW = m[3].length;
19145
19146 return m;
19147 }).map(forceLeft ? alignLeft :
19148 isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
19149
19150 function spaces(n) {
19151 return lang.stringRepeat(" ", n);
19152 }
19153
19154 function alignLeft(m) {
19155 return !m[2] ? m[0] : spaces(startW) + m[2]
19156 + spaces(textW - m[2].length + endW)
19157 + m[4].replace(/^([=:])\s+/, "$1 ");
19158 }
19159 function alignRight(m) {
19160 return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
19161 + spaces(endW)
19162 + m[4].replace(/^([=:])\s+/, "$1 ");
19163 }
19164 function unAlign(m) {
19165 return !m[2] ? m[0] : spaces(startW) + m[2]
19166 + spaces(endW)
19167 + m[4].replace(/^([=:])\s+/, "$1 ");
19168 }
19169 };
19170}).call(Editor.prototype);
19171
19172
19173function isSamePoint(p1, p2) {
19174 return p1.row == p2.row && p1.column == p2.column;
19175}
19176exports.onSessionChange = function(e) {
19177 var session = e.session;
19178 if (session && !session.multiSelect) {
19179 session.$selectionMarkers = [];
19180 session.selection.$initRangeList();
19181 session.multiSelect = session.selection;
19182 }
19183 this.multiSelect = session && session.multiSelect;
19184
19185 var oldSession = e.oldSession;
19186 if (oldSession) {
19187 oldSession.multiSelect.off("addRange", this.$onAddRange);
19188 oldSession.multiSelect.off("removeRange", this.$onRemoveRange);
19189 oldSession.multiSelect.off("multiSelect", this.$onMultiSelect);
19190 oldSession.multiSelect.off("singleSelect", this.$onSingleSelect);
19191 oldSession.multiSelect.lead.off("change", this.$checkMultiselectChange);
19192 oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange);
19193 }
19194
19195 if (session) {
19196 session.multiSelect.on("addRange", this.$onAddRange);
19197 session.multiSelect.on("removeRange", this.$onRemoveRange);
19198 session.multiSelect.on("multiSelect", this.$onMultiSelect);
19199 session.multiSelect.on("singleSelect", this.$onSingleSelect);
19200 session.multiSelect.lead.on("change", this.$checkMultiselectChange);
19201 session.multiSelect.anchor.on("change", this.$checkMultiselectChange);
19202 }
19203
19204 if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {
19205 if (session.selection.inMultiSelectMode)
19206 this.$onMultiSelect();
19207 else
19208 this.$onSingleSelect();
19209 }
19210};
19211function MultiSelect(editor) {
19212 if (editor.$multiselectOnSessionChange)
19213 return;
19214 editor.$onAddRange = editor.$onAddRange.bind(editor);
19215 editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
19216 editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
19217 editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
19218 editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);
19219 editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);
19220
19221 editor.$multiselectOnSessionChange(editor);
19222 editor.on("changeSession", editor.$multiselectOnSessionChange);
19223
19224 editor.on("mousedown", onMouseDown);
19225 editor.commands.addCommands(commands.defaultCommands);
19226
19227 addAltCursorListeners(editor);
19228}
19229
19230function addAltCursorListeners(editor){
19231 var el = editor.textInput.getElement();
19232 var altCursor = false;
19233 event.addListener(el, "keydown", function(e) {
19234 var altDown = e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey);
19235 if (editor.$blockSelectEnabled && altDown) {
19236 if (!altCursor) {
19237 editor.renderer.setMouseCursor("crosshair");
19238 altCursor = true;
19239 }
19240 } else if (altCursor) {
19241 reset();
19242 }
19243 });
19244
19245 event.addListener(el, "keyup", reset);
19246 event.addListener(el, "blur", reset);
19247 function reset(e) {
19248 if (altCursor) {
19249 editor.renderer.setMouseCursor("");
19250 altCursor = false;
19251 }
19252 }
19253}
19254
19255exports.MultiSelect = MultiSelect;
19256
19257
19258acequire("./config").defineOptions(Editor.prototype, "editor", {
19259 enableMultiselect: {
19260 set: function(val) {
19261 MultiSelect(this);
19262 if (val) {
19263 this.on("changeSession", this.$multiselectOnSessionChange);
19264 this.on("mousedown", onMouseDown);
19265 } else {
19266 this.off("changeSession", this.$multiselectOnSessionChange);
19267 this.off("mousedown", onMouseDown);
19268 }
19269 },
19270 value: true
19271 },
19272 enableBlockSelect: {
19273 set: function(val) {
19274 this.$blockSelectEnabled = val;
19275 },
19276 value: true
19277 }
19278});
19279
19280
19281
19282});
19283
19284ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"], function(acequire, exports, module) {
19285
19286var Range = acequire("../../range").Range;
19287
19288var FoldMode = exports.FoldMode = function() {};
19289
19290(function() {
19291
19292 this.foldingStartMarker = null;
19293 this.foldingStopMarker = null;
19294 this.getFoldWidget = function(session, foldStyle, row) {
19295 var line = session.getLine(row);
19296 if (this.foldingStartMarker.test(line))
19297 return "start";
19298 if (foldStyle == "markbeginend"
19299 && this.foldingStopMarker
19300 && this.foldingStopMarker.test(line))
19301 return "end";
19302 return "";
19303 };
19304
19305 this.getFoldWidgetRange = function(session, foldStyle, row) {
19306 return null;
19307 };
19308
19309 this.indentationBlock = function(session, row, column) {
19310 var re = /\S/;
19311 var line = session.getLine(row);
19312 var startLevel = line.search(re);
19313 if (startLevel == -1)
19314 return;
19315
19316 var startColumn = column || line.length;
19317 var maxRow = session.getLength();
19318 var startRow = row;
19319 var endRow = row;
19320
19321 while (++row < maxRow) {
19322 var level = session.getLine(row).search(re);
19323
19324 if (level == -1)
19325 continue;
19326
19327 if (level <= startLevel)
19328 break;
19329
19330 endRow = row;
19331 }
19332
19333 if (endRow > startRow) {
19334 var endColumn = session.getLine(endRow).length;
19335 return new Range(startRow, startColumn, endRow, endColumn);
19336 }
19337 };
19338
19339 this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
19340 var start = {row: row, column: column + 1};
19341 var end = session.$findClosingBracket(bracket, start, typeRe);
19342 if (!end)
19343 return;
19344
19345 var fw = session.foldWidgets[end.row];
19346 if (fw == null)
19347 fw = session.getFoldWidget(end.row);
19348
19349 if (fw == "start" && end.row > start.row) {
19350 end.row --;
19351 end.column = session.getLine(end.row).length;
19352 }
19353 return Range.fromPoints(start, end);
19354 };
19355
19356 this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
19357 var end = {row: row, column: column};
19358 var start = session.$findOpeningBracket(bracket, end);
19359
19360 if (!start)
19361 return;
19362
19363 start.column++;
19364 end.column--;
19365
19366 return Range.fromPoints(start, end);
19367 };
19368}).call(FoldMode.prototype);
19369
19370});
19371
19372ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) {
19373
19374exports.isDark = false;
19375exports.cssClass = "ace-tm";
19376exports.cssText = ".ace-tm .ace_gutter {\
19377background: #f0f0f0;\
19378color: #333;\
19379}\
19380.ace-tm .ace_print-margin {\
19381width: 1px;\
19382background: #e8e8e8;\
19383}\
19384.ace-tm .ace_fold {\
19385background-color: #6B72E6;\
19386}\
19387.ace-tm {\
19388background-color: #FFFFFF;\
19389color: black;\
19390}\
19391.ace-tm .ace_cursor {\
19392color: black;\
19393}\
19394.ace-tm .ace_invisible {\
19395color: rgb(191, 191, 191);\
19396}\
19397.ace-tm .ace_storage,\
19398.ace-tm .ace_keyword {\
19399color: blue;\
19400}\
19401.ace-tm .ace_constant {\
19402color: rgb(197, 6, 11);\
19403}\
19404.ace-tm .ace_constant.ace_buildin {\
19405color: rgb(88, 72, 246);\
19406}\
19407.ace-tm .ace_constant.ace_language {\
19408color: rgb(88, 92, 246);\
19409}\
19410.ace-tm .ace_constant.ace_library {\
19411color: rgb(6, 150, 14);\
19412}\
19413.ace-tm .ace_invalid {\
19414background-color: rgba(255, 0, 0, 0.1);\
19415color: red;\
19416}\
19417.ace-tm .ace_support.ace_function {\
19418color: rgb(60, 76, 114);\
19419}\
19420.ace-tm .ace_support.ace_constant {\
19421color: rgb(6, 150, 14);\
19422}\
19423.ace-tm .ace_support.ace_type,\
19424.ace-tm .ace_support.ace_class {\
19425color: rgb(109, 121, 222);\
19426}\
19427.ace-tm .ace_keyword.ace_operator {\
19428color: rgb(104, 118, 135);\
19429}\
19430.ace-tm .ace_string {\
19431color: rgb(3, 106, 7);\
19432}\
19433.ace-tm .ace_comment {\
19434color: rgb(76, 136, 107);\
19435}\
19436.ace-tm .ace_comment.ace_doc {\
19437color: rgb(0, 102, 255);\
19438}\
19439.ace-tm .ace_comment.ace_doc.ace_tag {\
19440color: rgb(128, 159, 191);\
19441}\
19442.ace-tm .ace_constant.ace_numeric {\
19443color: rgb(0, 0, 205);\
19444}\
19445.ace-tm .ace_variable {\
19446color: rgb(49, 132, 149);\
19447}\
19448.ace-tm .ace_xml-pe {\
19449color: rgb(104, 104, 91);\
19450}\
19451.ace-tm .ace_entity.ace_name.ace_function {\
19452color: #0000A2;\
19453}\
19454.ace-tm .ace_heading {\
19455color: rgb(12, 7, 255);\
19456}\
19457.ace-tm .ace_list {\
19458color:rgb(185, 6, 144);\
19459}\
19460.ace-tm .ace_meta.ace_tag {\
19461color:rgb(0, 22, 142);\
19462}\
19463.ace-tm .ace_string.ace_regex {\
19464color: rgb(255, 0, 0)\
19465}\
19466.ace-tm .ace_marker-layer .ace_selection {\
19467background: rgb(181, 213, 255);\
19468}\
19469.ace-tm.ace_multiselect .ace_selection.ace_start {\
19470box-shadow: 0 0 3px 0px white;\
19471}\
19472.ace-tm .ace_marker-layer .ace_step {\
19473background: rgb(252, 255, 0);\
19474}\
19475.ace-tm .ace_marker-layer .ace_stack {\
19476background: rgb(164, 229, 101);\
19477}\
19478.ace-tm .ace_marker-layer .ace_bracket {\
19479margin: -1px 0 0 -1px;\
19480border: 1px solid rgb(192, 192, 192);\
19481}\
19482.ace-tm .ace_marker-layer .ace_active-line {\
19483background: rgba(0, 0, 0, 0.07);\
19484}\
19485.ace-tm .ace_gutter-active-line {\
19486background-color : #dcdcdc;\
19487}\
19488.ace-tm .ace_marker-layer .ace_selected-word {\
19489background: rgb(250, 250, 255);\
19490border: 1px solid rgb(200, 200, 250);\
19491}\
19492.ace-tm .ace_indent-guide {\
19493background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
19494}\
19495";
19496
19497var dom = acequire("../lib/dom");
19498dom.importCssString(exports.cssText, exports.cssClass);
19499});
19500
19501ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(acequire, exports, module) {
19502
19503acequire("./lib/oop");
19504var dom = acequire("./lib/dom");
19505acequire("./range").Range;
19506
19507
19508function LineWidgets(session) {
19509 this.session = session;
19510 this.session.widgetManager = this;
19511 this.session.getRowLength = this.getRowLength;
19512 this.session.$getWidgetScreenLength = this.$getWidgetScreenLength;
19513 this.updateOnChange = this.updateOnChange.bind(this);
19514 this.renderWidgets = this.renderWidgets.bind(this);
19515 this.measureWidgets = this.measureWidgets.bind(this);
19516 this.session._changedWidgets = [];
19517 this.$onChangeEditor = this.$onChangeEditor.bind(this);
19518
19519 this.session.on("change", this.updateOnChange);
19520 this.session.on("changeFold", this.updateOnFold);
19521 this.session.on("changeEditor", this.$onChangeEditor);
19522}
19523
19524(function() {
19525 this.getRowLength = function(row) {
19526 var h;
19527 if (this.lineWidgets)
19528 h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
19529 else
19530 h = 0;
19531 if (!this.$useWrapMode || !this.$wrapData[row]) {
19532 return 1 + h;
19533 } else {
19534 return this.$wrapData[row].length + 1 + h;
19535 }
19536 };
19537
19538 this.$getWidgetScreenLength = function() {
19539 var screenRows = 0;
19540 this.lineWidgets.forEach(function(w){
19541 if (w && w.rowCount && !w.hidden)
19542 screenRows += w.rowCount;
19543 });
19544 return screenRows;
19545 };
19546
19547 this.$onChangeEditor = function(e) {
19548 this.attach(e.editor);
19549 };
19550
19551 this.attach = function(editor) {
19552 if (editor && editor.widgetManager && editor.widgetManager != this)
19553 editor.widgetManager.detach();
19554
19555 if (this.editor == editor)
19556 return;
19557
19558 this.detach();
19559 this.editor = editor;
19560
19561 if (editor) {
19562 editor.widgetManager = this;
19563 editor.renderer.on("beforeRender", this.measureWidgets);
19564 editor.renderer.on("afterRender", this.renderWidgets);
19565 }
19566 };
19567 this.detach = function(e) {
19568 var editor = this.editor;
19569 if (!editor)
19570 return;
19571
19572 this.editor = null;
19573 editor.widgetManager = null;
19574
19575 editor.renderer.off("beforeRender", this.measureWidgets);
19576 editor.renderer.off("afterRender", this.renderWidgets);
19577 var lineWidgets = this.session.lineWidgets;
19578 lineWidgets && lineWidgets.forEach(function(w) {
19579 if (w && w.el && w.el.parentNode) {
19580 w._inDocument = false;
19581 w.el.parentNode.removeChild(w.el);
19582 }
19583 });
19584 };
19585
19586 this.updateOnFold = function(e, session) {
19587 var lineWidgets = session.lineWidgets;
19588 if (!lineWidgets || !e.action)
19589 return;
19590 var fold = e.data;
19591 var start = fold.start.row;
19592 var end = fold.end.row;
19593 var hide = e.action == "add";
19594 for (var i = start + 1; i < end; i++) {
19595 if (lineWidgets[i])
19596 lineWidgets[i].hidden = hide;
19597 }
19598 if (lineWidgets[end]) {
19599 if (hide) {
19600 if (!lineWidgets[start])
19601 lineWidgets[start] = lineWidgets[end];
19602 else
19603 lineWidgets[end].hidden = hide;
19604 } else {
19605 if (lineWidgets[start] == lineWidgets[end])
19606 lineWidgets[start] = undefined;
19607 lineWidgets[end].hidden = hide;
19608 }
19609 }
19610 };
19611
19612 this.updateOnChange = function(delta) {
19613 var lineWidgets = this.session.lineWidgets;
19614 if (!lineWidgets) return;
19615
19616 var startRow = delta.start.row;
19617 var len = delta.end.row - startRow;
19618
19619 if (len === 0) ; else if (delta.action == 'remove') {
19620 var removed = lineWidgets.splice(startRow + 1, len);
19621 removed.forEach(function(w) {
19622 w && this.removeLineWidget(w);
19623 }, this);
19624 this.$updateRows();
19625 } else {
19626 var args = new Array(len);
19627 args.unshift(startRow, 0);
19628 lineWidgets.splice.apply(lineWidgets, args);
19629 this.$updateRows();
19630 }
19631 };
19632
19633 this.$updateRows = function() {
19634 var lineWidgets = this.session.lineWidgets;
19635 if (!lineWidgets) return;
19636 var noWidgets = true;
19637 lineWidgets.forEach(function(w, i) {
19638 if (w) {
19639 noWidgets = false;
19640 w.row = i;
19641 while (w.$oldWidget) {
19642 w.$oldWidget.row = i;
19643 w = w.$oldWidget;
19644 }
19645 }
19646 });
19647 if (noWidgets)
19648 this.session.lineWidgets = null;
19649 };
19650
19651 this.addLineWidget = function(w) {
19652 if (!this.session.lineWidgets)
19653 this.session.lineWidgets = new Array(this.session.getLength());
19654
19655 var old = this.session.lineWidgets[w.row];
19656 if (old) {
19657 w.$oldWidget = old;
19658 if (old.el && old.el.parentNode) {
19659 old.el.parentNode.removeChild(old.el);
19660 old._inDocument = false;
19661 }
19662 }
19663
19664 this.session.lineWidgets[w.row] = w;
19665
19666 w.session = this.session;
19667
19668 var renderer = this.editor.renderer;
19669 if (w.html && !w.el) {
19670 w.el = dom.createElement("div");
19671 w.el.innerHTML = w.html;
19672 }
19673 if (w.el) {
19674 dom.addCssClass(w.el, "ace_lineWidgetContainer");
19675 w.el.style.position = "absolute";
19676 w.el.style.zIndex = 5;
19677 renderer.container.appendChild(w.el);
19678 w._inDocument = true;
19679 }
19680
19681 if (!w.coverGutter) {
19682 w.el.style.zIndex = 3;
19683 }
19684 if (w.pixelHeight == null) {
19685 w.pixelHeight = w.el.offsetHeight;
19686 }
19687 if (w.rowCount == null) {
19688 w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
19689 }
19690
19691 var fold = this.session.getFoldAt(w.row, 0);
19692 w.$fold = fold;
19693 if (fold) {
19694 var lineWidgets = this.session.lineWidgets;
19695 if (w.row == fold.end.row && !lineWidgets[fold.start.row])
19696 lineWidgets[fold.start.row] = w;
19697 else
19698 w.hidden = true;
19699 }
19700
19701 this.session._emit("changeFold", {data:{start:{row: w.row}}});
19702
19703 this.$updateRows();
19704 this.renderWidgets(null, renderer);
19705 this.onWidgetChanged(w);
19706 return w;
19707 };
19708
19709 this.removeLineWidget = function(w) {
19710 w._inDocument = false;
19711 w.session = null;
19712 if (w.el && w.el.parentNode)
19713 w.el.parentNode.removeChild(w.el);
19714 if (w.editor && w.editor.destroy) try {
19715 w.editor.destroy();
19716 } catch(e){}
19717 if (this.session.lineWidgets) {
19718 var w1 = this.session.lineWidgets[w.row];
19719 if (w1 == w) {
19720 this.session.lineWidgets[w.row] = w.$oldWidget;
19721 if (w.$oldWidget)
19722 this.onWidgetChanged(w.$oldWidget);
19723 } else {
19724 while (w1) {
19725 if (w1.$oldWidget == w) {
19726 w1.$oldWidget = w.$oldWidget;
19727 break;
19728 }
19729 w1 = w1.$oldWidget;
19730 }
19731 }
19732 }
19733 this.session._emit("changeFold", {data:{start:{row: w.row}}});
19734 this.$updateRows();
19735 };
19736
19737 this.getWidgetsAtRow = function(row) {
19738 var lineWidgets = this.session.lineWidgets;
19739 var w = lineWidgets && lineWidgets[row];
19740 var list = [];
19741 while (w) {
19742 list.push(w);
19743 w = w.$oldWidget;
19744 }
19745 return list;
19746 };
19747
19748 this.onWidgetChanged = function(w) {
19749 this.session._changedWidgets.push(w);
19750 this.editor && this.editor.renderer.updateFull();
19751 };
19752
19753 this.measureWidgets = function(e, renderer) {
19754 var changedWidgets = this.session._changedWidgets;
19755 var config = renderer.layerConfig;
19756
19757 if (!changedWidgets || !changedWidgets.length) return;
19758 var min = Infinity;
19759 for (var i = 0; i < changedWidgets.length; i++) {
19760 var w = changedWidgets[i];
19761 if (!w || !w.el) continue;
19762 if (w.session != this.session) continue;
19763 if (!w._inDocument) {
19764 if (this.session.lineWidgets[w.row] != w)
19765 continue;
19766 w._inDocument = true;
19767 renderer.container.appendChild(w.el);
19768 }
19769
19770 w.h = w.el.offsetHeight;
19771
19772 if (!w.fixedWidth) {
19773 w.w = w.el.offsetWidth;
19774 w.screenWidth = Math.ceil(w.w / config.characterWidth);
19775 }
19776
19777 var rowCount = w.h / config.lineHeight;
19778 if (w.coverLine) {
19779 rowCount -= this.session.getRowLineCount(w.row);
19780 if (rowCount < 0)
19781 rowCount = 0;
19782 }
19783 if (w.rowCount != rowCount) {
19784 w.rowCount = rowCount;
19785 if (w.row < min)
19786 min = w.row;
19787 }
19788 }
19789 if (min != Infinity) {
19790 this.session._emit("changeFold", {data:{start:{row: min}}});
19791 this.session.lineWidgetWidth = null;
19792 }
19793 this.session._changedWidgets = [];
19794 };
19795
19796 this.renderWidgets = function(e, renderer) {
19797 var config = renderer.layerConfig;
19798 var lineWidgets = this.session.lineWidgets;
19799 if (!lineWidgets)
19800 return;
19801 var first = Math.min(this.firstRow, config.firstRow);
19802 var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);
19803
19804 while (first > 0 && !lineWidgets[first])
19805 first--;
19806
19807 this.firstRow = config.firstRow;
19808 this.lastRow = config.lastRow;
19809
19810 renderer.$cursorLayer.config = config;
19811 for (var i = first; i <= last; i++) {
19812 var w = lineWidgets[i];
19813 if (!w || !w.el) continue;
19814 if (w.hidden) {
19815 w.el.style.top = -100 - (w.pixelHeight || 0) + "px";
19816 continue;
19817 }
19818 if (!w._inDocument) {
19819 w._inDocument = true;
19820 renderer.container.appendChild(w.el);
19821 }
19822 var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top;
19823 if (!w.coverLine)
19824 top += config.lineHeight * this.session.getRowLineCount(w.row);
19825 w.el.style.top = top - config.offset + "px";
19826
19827 var left = w.coverGutter ? 0 : renderer.gutterWidth;
19828 if (!w.fixedWidth)
19829 left -= renderer.scrollLeft;
19830 w.el.style.left = left + "px";
19831
19832 if (w.fullWidth && w.screenWidth) {
19833 w.el.style.minWidth = config.width + 2 * config.padding + "px";
19834 }
19835
19836 if (w.fixedWidth) {
19837 w.el.style.right = renderer.scrollBar.getWidth() + "px";
19838 } else {
19839 w.el.style.right = "";
19840 }
19841 }
19842 };
19843
19844}).call(LineWidgets.prototype);
19845
19846
19847exports.LineWidgets = LineWidgets;
19848
19849});
19850
19851ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"], function(acequire, exports, module) {
19852var LineWidgets = acequire("../line_widgets").LineWidgets;
19853var dom = acequire("../lib/dom");
19854var Range = acequire("../range").Range;
19855
19856function binarySearch(array, needle, comparator) {
19857 var first = 0;
19858 var last = array.length - 1;
19859
19860 while (first <= last) {
19861 var mid = (first + last) >> 1;
19862 var c = comparator(needle, array[mid]);
19863 if (c > 0)
19864 first = mid + 1;
19865 else if (c < 0)
19866 last = mid - 1;
19867 else
19868 return mid;
19869 }
19870 return -(first + 1);
19871}
19872
19873function findAnnotations(session, row, dir) {
19874 var annotations = session.getAnnotations().sort(Range.comparePoints);
19875 if (!annotations.length)
19876 return;
19877
19878 var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints);
19879 if (i < 0)
19880 i = -i - 1;
19881
19882 if (i >= annotations.length)
19883 i = dir > 0 ? 0 : annotations.length - 1;
19884 else if (i === 0 && dir < 0)
19885 i = annotations.length - 1;
19886
19887 var annotation = annotations[i];
19888 if (!annotation || !dir)
19889 return;
19890
19891 if (annotation.row === row) {
19892 do {
19893 annotation = annotations[i += dir];
19894 } while (annotation && annotation.row === row);
19895 if (!annotation)
19896 return annotations.slice();
19897 }
19898
19899
19900 var matched = [];
19901 row = annotation.row;
19902 do {
19903 matched[dir < 0 ? "unshift" : "push"](annotation);
19904 annotation = annotations[i += dir];
19905 } while (annotation && annotation.row == row);
19906 return matched.length && matched;
19907}
19908
19909exports.showErrorMarker = function(editor, dir) {
19910 var session = editor.session;
19911 if (!session.widgetManager) {
19912 session.widgetManager = new LineWidgets(session);
19913 session.widgetManager.attach(editor);
19914 }
19915
19916 var pos = editor.getCursorPosition();
19917 var row = pos.row;
19918 var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) {
19919 return w.type == "errorMarker";
19920 })[0];
19921 if (oldWidget) {
19922 oldWidget.destroy();
19923 } else {
19924 row -= dir;
19925 }
19926 var annotations = findAnnotations(session, row, dir);
19927 var gutterAnno;
19928 if (annotations) {
19929 var annotation = annotations[0];
19930 pos.column = (annotation.pos && typeof annotation.column != "number"
19931 ? annotation.pos.sc
19932 : annotation.column) || 0;
19933 pos.row = annotation.row;
19934 gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row];
19935 } else if (oldWidget) {
19936 return;
19937 } else {
19938 gutterAnno = {
19939 text: ["Looks good!"],
19940 className: "ace_ok"
19941 };
19942 }
19943 editor.session.unfold(pos.row);
19944 editor.selection.moveToPosition(pos);
19945
19946 var w = {
19947 row: pos.row,
19948 fixedWidth: true,
19949 coverGutter: true,
19950 el: dom.createElement("div"),
19951 type: "errorMarker"
19952 };
19953 var el = w.el.appendChild(dom.createElement("div"));
19954 var arrow = w.el.appendChild(dom.createElement("div"));
19955 arrow.className = "error_widget_arrow " + gutterAnno.className;
19956
19957 var left = editor.renderer.$cursorLayer
19958 .getPixelPosition(pos).left;
19959 arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px";
19960
19961 w.el.className = "error_widget_wrapper";
19962 el.className = "error_widget " + gutterAnno.className;
19963 el.innerHTML = gutterAnno.text.join("<br>");
19964
19965 el.appendChild(dom.createElement("div"));
19966
19967 var kb = function(_, hashId, keyString) {
19968 if (hashId === 0 && (keyString === "esc" || keyString === "return")) {
19969 w.destroy();
19970 return {command: "null"};
19971 }
19972 };
19973
19974 w.destroy = function() {
19975 if (editor.$mouseHandler.isMousePressed)
19976 return;
19977 editor.keyBinding.removeKeyboardHandler(kb);
19978 session.widgetManager.removeLineWidget(w);
19979 editor.off("changeSelection", w.destroy);
19980 editor.off("changeSession", w.destroy);
19981 editor.off("mouseup", w.destroy);
19982 editor.off("change", w.destroy);
19983 };
19984
19985 editor.keyBinding.addKeyboardHandler(kb);
19986 editor.on("changeSelection", w.destroy);
19987 editor.on("changeSession", w.destroy);
19988 editor.on("mouseup", w.destroy);
19989 editor.on("change", w.destroy);
19990
19991 editor.session.widgetManager.addLineWidget(w);
19992
19993 w.el.onmousedown = editor.focus.bind(editor);
19994
19995 editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight});
19996};
19997
19998
19999dom.importCssString("\
20000 .error_widget_wrapper {\
20001 background: inherit;\
20002 color: inherit;\
20003 border:none\
20004 }\
20005 .error_widget {\
20006 border-top: solid 2px;\
20007 border-bottom: solid 2px;\
20008 margin: 5px 0;\
20009 padding: 10px 40px;\
20010 white-space: pre-wrap;\
20011 }\
20012 .error_widget.ace_error, .error_widget_arrow.ace_error{\
20013 border-color: #ff5a5a\
20014 }\
20015 .error_widget.ace_warning, .error_widget_arrow.ace_warning{\
20016 border-color: #F1D817\
20017 }\
20018 .error_widget.ace_info, .error_widget_arrow.ace_info{\
20019 border-color: #5a5a5a\
20020 }\
20021 .error_widget.ace_ok, .error_widget_arrow.ace_ok{\
20022 border-color: #5aaa5a\
20023 }\
20024 .error_widget_arrow {\
20025 position: absolute;\
20026 border: solid 5px;\
20027 border-top-color: transparent!important;\
20028 border-right-color: transparent!important;\
20029 border-left-color: transparent!important;\
20030 top: -5px;\
20031 }\
20032", "");
20033
20034});
20035
20036ace.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) {
20037
20038acequire("./lib/fixoldbrowsers");
20039
20040var dom = acequire("./lib/dom");
20041var event = acequire("./lib/event");
20042
20043var Editor = acequire("./editor").Editor;
20044var EditSession = acequire("./edit_session").EditSession;
20045var UndoManager = acequire("./undomanager").UndoManager;
20046var Renderer = acequire("./virtual_renderer").VirtualRenderer;
20047acequire("./worker/worker_client");
20048acequire("./keyboard/hash_handler");
20049acequire("./placeholder");
20050acequire("./multi_select");
20051acequire("./mode/folding/fold_mode");
20052acequire("./theme/textmate");
20053acequire("./ext/error_marker");
20054
20055exports.config = acequire("./config");
20056exports.acequire = acequire;
20057exports.edit = function(el) {
20058 if (typeof el == "string") {
20059 var _id = el;
20060 el = document.getElementById(_id);
20061 if (!el)
20062 throw new Error("ace.edit can't find div #" + _id);
20063 }
20064
20065 if (el && el.env && el.env.editor instanceof Editor)
20066 return el.env.editor;
20067
20068 var value = "";
20069 if (el && /input|textarea/i.test(el.tagName)) {
20070 var oldNode = el;
20071 value = oldNode.value;
20072 el = dom.createElement("pre");
20073 oldNode.parentNode.replaceChild(el, oldNode);
20074 } else if (el) {
20075 value = dom.getInnerText(el);
20076 el.innerHTML = "";
20077 }
20078
20079 var doc = exports.createEditSession(value);
20080
20081 var editor = new Editor(new Renderer(el));
20082 editor.setSession(doc);
20083
20084 var env = {
20085 document: doc,
20086 editor: editor,
20087 onResize: editor.resize.bind(editor, null)
20088 };
20089 if (oldNode) env.textarea = oldNode;
20090 event.addListener(window, "resize", env.onResize);
20091 editor.on("destroy", function() {
20092 event.removeListener(window, "resize", env.onResize);
20093 env.editor.container.env = null; // prevent memory leak on old ie
20094 });
20095 editor.container.env = editor.env = env;
20096 return editor;
20097};
20098exports.createEditSession = function(text, mode) {
20099 var doc = new EditSession(text, mode);
20100 doc.setUndoManager(new UndoManager());
20101 return doc;
20102};
20103exports.EditSession = EditSession;
20104exports.UndoManager = UndoManager;
20105exports.version = "1.2.9";
20106});
20107 (function() {
20108 ace.acequire(["ace/ace"], function(a) {
20109 if (a) {
20110 a.config.init(true);
20111 a.define = ace.define;
20112 }
20113 if (!window.ace)
20114 window.ace = a;
20115 for (var key in a) if (a.hasOwnProperty(key))
20116 window.ace[key] = a[key];
20117 });
20118 })();
20119
20120var brace = window.ace.acequire("ace/ace");
20121
20122var script = {
20123 name: 'FeiEditor',
20124 props: {
20125 modelValue: String,
20126 lang: {
20127 type: String,
20128 default: 'json'
20129 },
20130 theme: {
20131 type: String,
20132 default: 'chrome'
20133 },
20134 height: {
20135 type: String,
20136 default: '350'
20137 },
20138 width: {
20139 type: String,
20140 default: '100%'
20141 },
20142 fontSize: {
20143 type: Number,
20144 default: 12
20145 },
20146 options: Object,
20147 readonly: Boolean,
20148 wrap: {
20149 type: Boolean,
20150 default: false
20151 },
20152 snippets: {
20153 type: Boolean,
20154 default: true
20155 },
20156 styles: {
20157 type: Object
20158 }
20159 },
20160 data() {
20161 return {
20162 editor: null,
20163 contentBackup: ''
20164 };
20165 },
20166 emits: ['blur', 'init', 'update:modelValue', 'change'],
20167 computed: {
20168 wrapStyles() {
20169 return {
20170 width: this.width ? this.px(this.width) : '100%',
20171 height: this.height ? this.px(this.height) : '100%',
20172 border: '1px solid #e8e8e8',
20173 ...this.styles
20174 };
20175 }
20176 },
20177 methods: {
20178 px(n) {
20179 return /^\d*$/.test(n) ? `${n}px` : n;
20180 },
20181 getValue() {
20182 return this.editor.getValue();
20183 },
20184 handleBlur(event) {
20185 this.$emit('blur', event);
20186 }
20187 },
20188 watch: {
20189 modelValue(val) {
20190 if (this.contentBackup !== val) {
20191 this.editor.session.setValue(val, 1);
20192 this.contentBackup = val;
20193 }
20194 },
20195 theme(newTheme) {
20196 this.editor.setTheme('ace/theme/' + newTheme);
20197 },
20198 lang(newLang) {
20199 this.editor.getSession().setMode('ace/mode/' + newLang);
20200 },
20201 options(newOption) {
20202 this.editor.setOptions(newOption);
20203 },
20204 fontSize(newSize) {
20205 this.editor.setFontSize(newSize); // 设置文字大小
20206 },
20207
20208 readonly(val) {
20209 this.editor.setReadOnly(val); // 设置只读
20210 },
20211
20212 height() {
20213 this.$nextTick(() => {
20214 this.editor.resize();
20215 });
20216 },
20217 width() {
20218 this.$nextTick(() => {
20219 this.editor.resize();
20220 });
20221 }
20222 },
20223 beforeUnmount() {
20224 this.editor.destroy();
20225 this.editor.container.remove();
20226 },
20227 mounted() {
20228 let vm = this;
20229 let lang = this.lang;
20230 let theme = this.theme;
20231 let editor = vm.editor = brace.edit(this.$el);
20232 editor.getSession().setMode('ace/mode/' + lang);
20233 editor.setTheme('ace/theme/' + theme);
20234 editor.$blockScrolling = Infinity;
20235 editor.setFontSize(this.fontSize); // 设置文字大小
20236 editor.setReadOnly(this.readonly); // 设置只读
20237 editor.getSession().setUseWrapMode(this.wrap);
20238 editor.setShowPrintMargin(false);
20239 editor.getSession().setTabSize(2);
20240 editor.setOptions({
20241 enableBasicAutocompletion: this.snippets,
20242 enableSnippets: this.snippets,
20243 enableLiveAutocompletion: this.snippets
20244 });
20245 this.$emit('init', editor);
20246 if (this.modelValue) {
20247 editor.setValue(this.modelValue, 1);
20248 editor.gotoLine(0, 0, false);
20249 }
20250 this.contentBackup = this.modelValue;
20251 editor.on('change', function () {
20252 let content = editor.getValue();
20253 vm.$emit('update:modelValue', content);
20254 vm.$emit('change', content);
20255 vm.contentBackup = content;
20256 });
20257 editor.on('blur', this.handleBlur);
20258 if (vm.options) {
20259 editor.setOptions(vm.options);
20260 }
20261 }
20262};
20263
20264function render(_ctx, _cache, $props, $setup, $data, $options) {
20265 return openBlock(), createElementBlock("div", {
20266 class: "fei-editor",
20267 style: normalizeStyle($options.wrapStyles)
20268 }, null, 4 /* STYLE */);
20269}
20270
20271script.render = render;
20272script.__file = "src/components/editor/index.vue";
20273
20274/**
20275 * @description 返回这个样式的颜色值
20276 * @param {String} type 样式名称 [ primary | success | warning | danger | text ]
20277 */
20278function typeColor(type) {
20279 if (type === void 0) {
20280 type = 'default';
20281 }
20282 let color = '';
20283 switch (type) {
20284 case 'primary':
20285 color = '#1089ff';
20286 break;
20287 case 'success':
20288 color = '#52c41a';
20289 break;
20290 case 'warning':
20291 color = '#fa8c16';
20292 break;
20293 case 'danger':
20294 color = '#f5222d';
20295 break;
20296 case 'default':
20297 color = '#35495E';
20298 break;
20299 default:
20300 color = type;
20301 break;
20302 }
20303 return color;
20304}
20305const print = function (text, type, back) {
20306 if (type === void 0) {
20307 type = 'default';
20308 }
20309 if (back === void 0) {
20310 back = false;
20311 }
20312 if (typeof text === 'object') {
20313 // 如果是对象则调用打印对象方式
20314 console.dir(text);
20315 return;
20316 }
20317 if (back) {
20318 // 如果是打印带背景图的
20319 console.log(`%c ${text} `, `background:${typeColor(type)}; padding: 2px; border-radius: 2px;color: #fff;`);
20320 } else {
20321 console.log(`%c ${text} `, `color: ${typeColor(type)};`);
20322 }
20323};
20324const pretty = function (title, text, type) {
20325 if (type === void 0) {
20326 type = 'primary';
20327 }
20328 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');
20329};
20330const primary = function (text, back) {
20331 if (back === void 0) {
20332 back = false;
20333 }
20334 print(text, 'primary', back);
20335};
20336const success = function (text, back) {
20337 if (back === void 0) {
20338 back = false;
20339 }
20340 print(text, 'success', back);
20341};
20342const info = function (text, back) {
20343 if (back === void 0) {
20344 back = false;
20345 }
20346 print(text, 'info', back);
20347};
20348const warning = function (text, back) {
20349 if (back === void 0) {
20350 back = false;
20351 }
20352 print(text, 'warning', back);
20353};
20354const danger = function (text, back) {
20355 if (back === void 0) {
20356 back = false;
20357 }
20358 print(text, 'danger', back);
20359};
20360const printVersion = function (title, version, link, type, fontSize, versionColor) {
20361 if (type === void 0) {
20362 type = 'primary';
20363 }
20364 if (fontSize === void 0) {
20365 fontSize = '20px';
20366 }
20367 if (versionColor === void 0) {
20368 versionColor = '#999';
20369 }
20370 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};`);
20371};
20372const log = {
20373 print,
20374 pretty,
20375 primary,
20376 info,
20377 success,
20378 warning,
20379 danger,
20380 printVersion
20381};
20382
20383var name = "fei-editor";
20384var description = "基于vue的代码编辑器插件";
20385var version$1 = "0.0.2";
20386var keywords = [
20387 "fei-editor",
20388 "vue3",
20389 "components"
20390];
20391var author = "yangmengfei";
20392var files = [
20393 "lib",
20394 "src"
20395];
20396var main = "lib/fei-editor.common.js";
20397var module = "src/components/editor/index.vue";
20398var unpkg = "lib/fei-editor.js";
20399var homepage = "https://ymf930.gitee.io/fei-editor/";
20400var license = "MIT";
20401var scripts = {
20402 dev: "webpack-dev-server --config build/webpack.dev.js",
20403 "build:demo": "rimraf docs && cross-env NODE_ENV=production webpack --config build/webpack.dev.js",
20404 build: "yarn clean-lib && yarn build:lib",
20405 "clean-lib": "rimraf lib",
20406 "build:lib": "rollup --config build/rollup.config.mjs --bundleConfigAsCjs",
20407 lint: "eslint ./src --ext .vue,.js,.ts",
20408 "lint-fix": "eslint --fix ./src --ext .vue,.js,.ts"
20409};
20410var dependencies = {
20411 brace: "^0.11.1"
20412};
20413var peerDependencies = {
20414 vue: "^3.2.47"
20415};
20416var devDependencies = {
20417 "@babel/cli": "^7.21.5",
20418 "@babel/core": "^7.21.8",
20419 "@babel/eslint-parser": "^7.21.8",
20420 "@babel/plugin-transform-runtime": "^7.21.4",
20421 "@babel/preset-env": "^7.21.5",
20422 "@babel/runtime": "^7.21.5",
20423 "@rollup/plugin-babel": "^6.0.3",
20424 "@rollup/plugin-commonjs": "^25.0.0",
20425 "@rollup/plugin-json": "^6.0.0",
20426 "@rollup/plugin-node-resolve": "^15.0.2",
20427 "@rollup/plugin-replace": "^5.0.2",
20428 "@rollup/plugin-terser": "^0.4.3",
20429 "@types/markdown-it": "^12.2.3",
20430 "@vue/babel-plugin-jsx": "^1.0.0",
20431 "@vue/compiler-sfc": "^3.3.4",
20432 "babel-loader": "^9.1.2",
20433 "babel-plugin-module-resolver": "^5.0.0",
20434 "babel-plugin-transform-class-properties": "^6.24.1",
20435 "cross-env": "^7.0.2",
20436 "css-loader": "^6.7.4",
20437 "css-minimizer-webpack-plugin": "^5.0.0",
20438 eslint: "^8.41.0",
20439 "eslint-plugin-vue": "^9.14.0",
20440 "f-ui-one": "^1.0.5",
20441 "file-loader": "^6.0.0",
20442 "file-save": "^0.2.0",
20443 gulp: "^4.0.2",
20444 "gulp-autoprefixer": "^8.0.0",
20445 "gulp-cssmin": "^0.2.0",
20446 "gulp-stylus": "^3.0.0",
20447 "highlight.js": "^11.8.0",
20448 "html-webpack-plugin": "^5.5.1",
20449 "markdown-it": "^13.0.1",
20450 "markdown-it-anchor": "^8.6.7",
20451 "markdown-it-chain": "^1.3.0",
20452 "markdown-it-container": "^3.0.0",
20453 "mini-css-extract-plugin": "^2.7.6",
20454 postcss: "^8.4.23",
20455 prettier: "^2.8.8",
20456 rimraf: "^5.0.1",
20457 rollup: "^3.23.0",
20458 "rollup-plugin-css-only": "^4.3.0",
20459 "rollup-plugin-peer-deps-external": "^2.2.4",
20460 "rollup-plugin-postcss": "^4.0.2",
20461 "rollup-plugin-vue": "^6.0.0-beta.11",
20462 "style-loader": "^3.3.3",
20463 stylus: "^0.59.0",
20464 "stylus-loader": "7.1.0",
20465 tinycolor2: "^1.4.2",
20466 transliteration: "^2.2.0",
20467 "url-loader": "^4.1.1",
20468 vue: "^3.3.4",
20469 "vue-loader": "^17.1.1",
20470 "vue-router": "^4.2.1",
20471 "vue-template-compiler": "^2.6.12",
20472 webpack: "^5.83.1",
20473 "webpack-bundle-analyzer": "^4.8.0",
20474 "webpack-cli": "^5.1.1",
20475 "webpack-dev-server": "^4.15.0"
20476};
20477var config = {
20478 name: name,
20479 description: description,
20480 version: version$1,
20481 keywords: keywords,
20482 author: author,
20483 files: files,
20484 main: main,
20485 module: module,
20486 unpkg: unpkg,
20487 homepage: homepage,
20488 "private": false,
20489 license: license,
20490 scripts: scripts,
20491 dependencies: dependencies,
20492 peerDependencies: peerDependencies,
20493 devDependencies: devDependencies
20494};
20495
20496const version = config.version; // version_ to fix tsc issue
20497
20498const install = function (app, options) {
20499 if (options === void 0) {
20500 options = {};
20501 }
20502 app.component(script.name, script);
20503 if (!options.disabledDoc) {
20504 log.printVersion(config.name, config.version, config.homepage, '#722ed1');
20505 }
20506 return app;
20507};
20508var index = {
20509 version,
20510 install
20511};
20512
20513export { script as Editor, index as default };