PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.5
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.5
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / assets / libs / ace / ace.js

ace.js in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.5, at assets/libs/ace/ace.js

20,271 lines 684.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Distributed under the BSD license:
3 *
4 * Copyright (c) 2010, Ajax.org B.V.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Ajax.org B.V. nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * ***** END LICENSE BLOCK ***** */
30
31 /**
32 * Define a module along with a payload
33 * @param module a name for the payload
34 * @param payload a function to call with (require, exports, module) params
35 */
36
37 (function() {
38
39 var ACE_NAMESPACE = "";
40
41 var global = (function() { return this; })();
42 if (!global && typeof window != "undefined") global = window; // strict mode
43
44
45 if (!ACE_NAMESPACE && typeof requirejs !== "undefined")
46 return;
47
48
49 var define = function(module, deps, payload) {
50 if (typeof module !== "string") {
51 if (define.original)
52 define.original.apply(this, arguments);
53 else {
54 console.error("dropping module because define wasn\'t a string.");
55 console.trace();
56 }
57 return;
58 }
59 if (arguments.length == 2)
60 payload = deps;
61 if (!define.modules[module]) {
62 define.payloads[module] = payload;
63 define.modules[module] = null;
64 }
65 };
66
67 define.modules = {};
68 define.payloads = {};
69
70 /**
71 * Get at functionality define()ed using the function above
72 */
73 var _require = function(parentId, module, callback) {
74 if (typeof module === "string") {
75 var payload = lookup(parentId, module);
76 if (payload != undefined) {
77 callback && callback();
78 return payload;
79 }
80 } else if (Object.prototype.toString.call(module) === "[object Array]") {
81 var params = [];
82 for (var i = 0, l = module.length; i < l; ++i) {
83 var dep = lookup(parentId, module[i]);
84 if (dep == undefined && require.original)
85 return;
86 params.push(dep);
87 }
88 return callback && callback.apply(null, params) || true;
89 }
90 };
91
92 var require = function(module, callback) {
93 var packagedModule = _require("", module, callback);
94 if (packagedModule == undefined && require.original)
95 return require.original.apply(this, arguments);
96 return packagedModule;
97 };
98
99 var normalizeModule = function(parentId, moduleName) {
100 // normalize plugin requires
101 if (moduleName.indexOf("!") !== -1) {
102 var chunks = moduleName.split("!");
103 return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
104 }
105 // normalize relative requires
106 if (moduleName.charAt(0) == ".") {
107 var base = parentId.split("/").slice(0, -1).join("/");
108 moduleName = base + "/" + moduleName;
109
110 while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
111 var previous = moduleName;
112 moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
113 }
114 }
115 return moduleName;
116 };
117
118 /**
119 * Internal function to lookup moduleNames and resolve them by calling the
120 * definition function if needed.
121 */
122 var lookup = function(parentId, moduleName) {
123 moduleName = normalizeModule(parentId, moduleName);
124
125 var module = define.modules[moduleName];
126 if (!module) {
127 module = define.payloads[moduleName];
128 if (typeof module === 'function') {
129 var exports = {};
130 var mod = {
131 id: moduleName,
132 uri: '',
133 exports: exports,
134 packaged: true
135 };
136
137 var req = function(module, callback) {
138 return _require(moduleName, module, callback);
139 };
140
141 var returnValue = module(req, exports, mod);
142 exports = returnValue || mod.exports;
143 define.modules[moduleName] = exports;
144 delete define.payloads[moduleName];
145 }
146 module = define.modules[moduleName] = exports || module;
147 }
148 return module;
149 };
150
151 function exportAce(ns) {
152 var root = global;
153 if (ns) {
154 if (!global[ns])
155 global[ns] = {};
156 root = global[ns];
157 }
158
159 if (!root.define || !root.define.packaged) {
160 define.original = root.define;
161 root.define = define;
162 root.define.packaged = true;
163 }
164
165 if (!root.require || !root.require.packaged) {
166 require.original = root.require;
167 root.require = require;
168 root.require.packaged = true;
169 }
170 }
171
172 exportAce(ACE_NAMESPACE);
173
174 })();
175
176 define("ace/lib/regexp",["require","exports","module"], function(require, exports, module) {
177 "use strict";
178
179 var real = {
180 exec: RegExp.prototype.exec,
181 test: RegExp.prototype.test,
182 match: String.prototype.match,
183 replace: String.prototype.replace,
184 split: String.prototype.split
185 },
186 compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
187 compliantLastIndexIncrement = function () {
188 var x = /^/g;
189 real.test.call(x, "");
190 return !x.lastIndex;
191 }();
192
193 if (compliantLastIndexIncrement && compliantExecNpcg)
194 return;
195 RegExp.prototype.exec = function (str) {
196 var match = real.exec.apply(this, arguments),
197 name, r2;
198 if ( typeof(str) == 'string' && match) {
199 if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
200 r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
201 real.replace.call(str.slice(match.index), r2, function () {
202 for (var i = 1; i < arguments.length - 2; i++) {
203 if (arguments[i] === undefined)
204 match[i] = undefined;
205 }
206 });
207 }
208 if (this._xregexp && this._xregexp.captureNames) {
209 for (var i = 1; i < match.length; i++) {
210 name = this._xregexp.captureNames[i - 1];
211 if (name)
212 match[name] = match[i];
213 }
214 }
215 if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
216 this.lastIndex--;
217 }
218 return match;
219 };
220 if (!compliantLastIndexIncrement) {
221 RegExp.prototype.test = function (str) {
222 var match = real.exec.call(this, str);
223 if (match && this.global && !match[0].length && (this.lastIndex > match.index))
224 this.lastIndex--;
225 return !!match;
226 };
227 }
228
229 function getNativeFlags (regex) {
230 return (regex.global ? "g" : "") +
231 (regex.ignoreCase ? "i" : "") +
232 (regex.multiline ? "m" : "") +
233 (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3
234 (regex.sticky ? "y" : "");
235 }
236
237 function indexOf (array, item, from) {
238 if (Array.prototype.indexOf) // Use the native array method if available
239 return array.indexOf(item, from);
240 for (var i = from || 0; i < array.length; i++) {
241 if (array[i] === item)
242 return i;
243 }
244 return -1;
245 }
246
247 });
248
249 define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) {
250
251 function Empty() {}
252
253 if (!Function.prototype.bind) {
254 Function.prototype.bind = function bind(that) { // .length is 1
255 var target = this;
256 if (typeof target != "function") {
257 throw new TypeError("Function.prototype.bind called on incompatible " + target);
258 }
259 var args = slice.call(arguments, 1); // for normal call
260 var bound = function () {
261
262 if (this instanceof bound) {
263
264 var result = target.apply(
265 this,
266 args.concat(slice.call(arguments))
267 );
268 if (Object(result) === result) {
269 return result;
270 }
271 return this;
272
273 } else {
274 return target.apply(
275 that,
276 args.concat(slice.call(arguments))
277 );
278
279 }
280
281 };
282 if(target.prototype) {
283 Empty.prototype = target.prototype;
284 bound.prototype = new Empty();
285 Empty.prototype = null;
286 }
287 return bound;
288 };
289 }
290 var call = Function.prototype.call;
291 var prototypeOfArray = Array.prototype;
292 var prototypeOfObject = Object.prototype;
293 var slice = prototypeOfArray.slice;
294 var _toString = call.bind(prototypeOfObject.toString);
295 var owns = call.bind(prototypeOfObject.hasOwnProperty);
296 var defineGetter;
297 var defineSetter;
298 var lookupGetter;
299 var lookupSetter;
300 var supportsAccessors;
301 if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
302 defineGetter = call.bind(prototypeOfObject.__defineGetter__);
303 defineSetter = call.bind(prototypeOfObject.__defineSetter__);
304 lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
305 lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
306 }
307 if ([1,2].splice(0).length != 2) {
308 if(function() { // test IE < 9 to splice bug - see issue #138
309 function makeArray(l) {
310 var a = new Array(l+2);
311 a[0] = a[1] = 0;
312 return a;
313 }
314 var array = [], lengthBefore;
315
316 array.splice.apply(array, makeArray(20));
317 array.splice.apply(array, makeArray(26));
318
319 lengthBefore = array.length; //46
320 array.splice(5, 0, "XXX"); // add one element
321
322 lengthBefore + 1 == array.length
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 }
392 if (!Array.isArray) {
393 Array.isArray = function isArray(obj) {
394 return _toString(obj) == "[object Array]";
395 };
396 }
397 var boxedString = Object("a"),
398 splitString = boxedString[0] != "a" || !(0 in boxedString);
399
400 if (!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 }
420 if (!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 }
440 if (!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 }
465 if (!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 }
485 if (!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 }
505 if (!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 }
544 if (!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 }
582 if (!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 }
606 if (!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 }
629 if (!Object.getPrototypeOf) {
630 Object.getPrototypeOf = function getPrototypeOf(object) {
631 return object.__proto__ || (
632 object.constructor ?
633 object.constructor.prototype :
634 prototypeOfObject
635 );
636 };
637 }
638 if (!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 }
667 if (!Object.getOwnPropertyNames) {
668 Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
669 return Object.keys(object);
670 };
671 }
672 if (!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
713 function doesDefinePropertyWork(object) {
714 try {
715 Object.defineProperty(object, "sentinel", {});
716 return "sentinel" in object;
717 } catch (exception) {
718 }
719 }
720 if (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
729 if (!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 }
771 if (!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 }
780 if (!Object.seal) {
781 Object.seal = function seal(object) {
782 return object;
783 };
784 }
785 if (!Object.freeze) {
786 Object.freeze = function freeze(object) {
787 return object;
788 };
789 }
790 try {
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 }
803 if (!Object.preventExtensions) {
804 Object.preventExtensions = function preventExtensions(object) {
805 return object;
806 };
807 }
808 if (!Object.isSealed) {
809 Object.isSealed = function isSealed(object) {
810 return false;
811 };
812 }
813 if (!Object.isFrozen) {
814 Object.isFrozen = function isFrozen(object) {
815 return false;
816 };
817 }
818 if (!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 }
833 if (!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 }
878 if (!Date.now) {
879 Date.now = function now() {
880 return new Date().getTime();
881 };
882 }
883 var 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";
886 if (!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
895 function 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 }
904
905 function isPrimitive(input) {
906 var type = typeof input;
907 return (
908 input === null ||
909 type === "undefined" ||
910 type === "boolean" ||
911 type === "number" ||
912 type === "string"
913 );
914 }
915
916 function toPrimitive(input) {
917 var val, valueOf, toString;
918 if (isPrimitive(input)) {
919 return input;
920 }
921 valueOf = input.valueOf;
922 if (typeof valueOf === "function") {
923 val = valueOf.call(input);
924 if (isPrimitive(val)) {
925 return val;
926 }
927 }
928 toString = input.toString;
929 if (typeof toString === "function") {
930 val = toString.call(input);
931 if (isPrimitive(val)) {
932 return val;
933 }
934 }
935 throw new TypeError();
936 }
937 var toObject = function (o) {
938 if (o == null) { // this matches both null and undefined
939 throw new TypeError("can't convert "+o+" to object");
940 }
941 return Object(o);
942 };
943
944 });
945
946 define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(require, exports, module) {
947 "use strict";
948
949 require("./regexp");
950 require("./es5-shim");
951
952 });
953
954 define("ace/lib/dom",["require","exports","module"], function(require, exports, module) {
955 "use strict";
956
957 var XHTML_NS = "http://www.w3.org/1999/xhtml";
958
959 exports.getDocumentHead = function(doc) {
960 if (!doc)
961 doc = document;
962 return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
963 };
964
965 exports.createElement = function(tag, ns) {
966 return document.createElementNS ?
967 document.createElementNS(ns || XHTML_NS, tag) :
968 document.createElement(tag);
969 };
970
971 exports.hasCssClass = function(el, name) {
972 var classes = (el.className + "").split(/\s+/g);
973 return classes.indexOf(name) !== -1;
974 };
975 exports.addCssClass = function(el, name) {
976 if (!exports.hasCssClass(el, name)) {
977 el.className += " " + name;
978 }
979 };
980 exports.removeCssClass = function(el, name) {
981 var classes = el.className.split(/\s+/g);
982 while (true) {
983 var index = classes.indexOf(name);
984 if (index == -1) {
985 break;
986 }
987 classes.splice(index, 1);
988 }
989 el.className = classes.join(" ");
990 };
991
992 exports.toggleCssClass = function(el, name) {
993 var classes = el.className.split(/\s+/g), add = true;
994 while (true) {
995 var index = classes.indexOf(name);
996 if (index == -1) {
997 break;
998 }
999 add = false;
1000 classes.splice(index, 1);
1001 }
1002 if (add)
1003 classes.push(name);
1004
1005 el.className = classes.join(" ");
1006 return add;
1007 };
1008 exports.setCssClass = function(node, className, include) {
1009 if (include) {
1010 exports.addCssClass(node, className);
1011 } else {
1012 exports.removeCssClass(node, className);
1013 }
1014 };
1015
1016 exports.hasCssString = function(id, doc) {
1017 var index = 0, sheets;
1018 doc = doc || document;
1019
1020 if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
1021 while (index < sheets.length)
1022 if (sheets[index++].owningElement.id === id) return true;
1023 } else if ((sheets = doc.getElementsByTagName("style"))) {
1024 while (index < sheets.length)
1025 if (sheets[index++].id === id) return true;
1026 }
1027
1028 return false;
1029 };
1030
1031 exports.importCssString = function importCssString(cssText, id, doc) {
1032 doc = doc || document;
1033 if (id && exports.hasCssString(id, doc))
1034 return null;
1035
1036 var style;
1037
1038 if (id)
1039 cssText += "\n/*# sourceURL=ace/css/" + id + " */";
1040
1041 if (doc.createStyleSheet) {
1042 style = doc.createStyleSheet();
1043 style.cssText = cssText;
1044 if (id)
1045 style.owningElement.id = id;
1046 } else {
1047 style = exports.createElement("style");
1048 style.appendChild(doc.createTextNode(cssText));
1049 if (id)
1050 style.id = id;
1051
1052 exports.getDocumentHead(doc).appendChild(style);
1053 }
1054 };
1055
1056 exports.importCssStylsheet = function(uri, doc) {
1057 if (doc.createStyleSheet) {
1058 doc.createStyleSheet(uri);
1059 } else {
1060 var link = exports.createElement('link');
1061 link.rel = 'stylesheet';
1062 link.href = uri;
1063
1064 exports.getDocumentHead(doc).appendChild(link);
1065 }
1066 };
1067
1068 exports.getInnerWidth = function(element) {
1069 return (
1070 parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
1071 parseInt(exports.computedStyle(element, "paddingRight"), 10) +
1072 element.clientWidth
1073 );
1074 };
1075
1076 exports.getInnerHeight = function(element) {
1077 return (
1078 parseInt(exports.computedStyle(element, "paddingTop"), 10) +
1079 parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
1080 element.clientHeight
1081 );
1082 };
1083
1084 exports.scrollbarWidth = function(document) {
1085 var inner = exports.createElement("ace_inner");
1086 inner.style.width = "100%";
1087 inner.style.minWidth = "0px";
1088 inner.style.height = "200px";
1089 inner.style.display = "block";
1090
1091 var outer = exports.createElement("ace_outer");
1092 var style = outer.style;
1093
1094 style.position = "absolute";
1095 style.left = "-10000px";
1096 style.overflow = "hidden";
1097 style.width = "200px";
1098 style.minWidth = "0px";
1099 style.height = "150px";
1100 style.display = "block";
1101
1102 outer.appendChild(inner);
1103
1104 var body = document.documentElement;
1105 body.appendChild(outer);
1106
1107 var noScrollbar = inner.offsetWidth;
1108
1109 style.overflow = "scroll";
1110 var withScrollbar = inner.offsetWidth;
1111
1112 if (noScrollbar == withScrollbar) {
1113 withScrollbar = outer.clientWidth;
1114 }
1115
1116 body.removeChild(outer);
1117
1118 return noScrollbar-withScrollbar;
1119 };
1120
1121 if (typeof document == "undefined") {
1122 exports.importCssString = function() {};
1123 return;
1124 }
1125
1126 if (window.pageYOffset !== undefined) {
1127 exports.getPageScrollTop = function() {
1128 return window.pageYOffset;
1129 };
1130
1131 exports.getPageScrollLeft = function() {
1132 return window.pageXOffset;
1133 };
1134 }
1135 else {
1136 exports.getPageScrollTop = function() {
1137 return document.body.scrollTop;
1138 };
1139
1140 exports.getPageScrollLeft = function() {
1141 return document.body.scrollLeft;
1142 };
1143 }
1144
1145 if (window.getComputedStyle)
1146 exports.computedStyle = function(element, style) {
1147 if (style)
1148 return (window.getComputedStyle(element, "") || {})[style] || "";
1149 return window.getComputedStyle(element, "") || {};
1150 };
1151 else
1152 exports.computedStyle = function(element, style) {
1153 if (style)
1154 return element.currentStyle[style];
1155 return element.currentStyle;
1156 };
1157 exports.setInnerHtml = function(el, innerHtml) {
1158 var element = el.cloneNode(false);//document.createElement("div");
1159 element.innerHTML = innerHtml;
1160 el.parentNode.replaceChild(element, el);
1161 return element;
1162 };
1163
1164 if ("textContent" in document.documentElement) {
1165 exports.setInnerText = function(el, innerText) {
1166 el.textContent = innerText;
1167 };
1168
1169 exports.getInnerText = function(el) {
1170 return el.textContent;
1171 };
1172 }
1173 else {
1174 exports.setInnerText = function(el, innerText) {
1175 el.innerText = innerText;
1176 };
1177
1178 exports.getInnerText = function(el) {
1179 return el.innerText;
1180 };
1181 }
1182
1183 exports.getParentWindow = function(document) {
1184 return document.defaultView || document.parentWindow;
1185 };
1186
1187 });
1188
1189 define("ace/lib/oop",["require","exports","module"], function(require, exports, module) {
1190 "use strict";
1191
1192 exports.inherits = function(ctor, superCtor) {
1193 ctor.super_ = superCtor;
1194 ctor.prototype = Object.create(superCtor.prototype, {
1195 constructor: {
1196 value: ctor,
1197 enumerable: false,
1198 writable: true,
1199 configurable: true
1200 }
1201 });
1202 };
1203
1204 exports.mixin = function(obj, mixin) {
1205 for (var key in mixin) {
1206 obj[key] = mixin[key];
1207 }
1208 return obj;
1209 };
1210
1211 exports.implement = function(proto, mixin) {
1212 exports.mixin(proto, mixin);
1213 };
1214
1215 });
1216
1217 define("ace/lib/keys",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop"], function(require, exports, module) {
1218 "use strict";
1219
1220 require("./fixoldbrowsers");
1221
1222 var oop = require("./oop");
1223 var Keys = (function() {
1224 var ret = {
1225 MODIFIER_KEYS: {
1226 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
1227 },
1228
1229 KEY_MODS: {
1230 "ctrl": 1, "alt": 2, "option" : 2, "shift": 4,
1231 "super": 8, "meta": 8, "command": 8, "cmd": 8
1232 },
1233
1234 FUNCTION_KEYS : {
1235 8 : "Backspace",
1236 9 : "Tab",
1237 13 : "Return",
1238 19 : "Pause",
1239 27 : "Esc",
1240 32 : "Space",
1241 33 : "PageUp",
1242 34 : "PageDown",
1243 35 : "End",
1244 36 : "Home",
1245 37 : "Left",
1246 38 : "Up",
1247 39 : "Right",
1248 40 : "Down",
1249 44 : "Print",
1250 45 : "Insert",
1251 46 : "Delete",
1252 96 : "Numpad0",
1253 97 : "Numpad1",
1254 98 : "Numpad2",
1255 99 : "Numpad3",
1256 100: "Numpad4",
1257 101: "Numpad5",
1258 102: "Numpad6",
1259 103: "Numpad7",
1260 104: "Numpad8",
1261 105: "Numpad9",
1262 '-13': "NumpadEnter",
1263 112: "F1",
1264 113: "F2",
1265 114: "F3",
1266 115: "F4",
1267 116: "F5",
1268 117: "F6",
1269 118: "F7",
1270 119: "F8",
1271 120: "F9",
1272 121: "F10",
1273 122: "F11",
1274 123: "F12",
1275 144: "Numlock",
1276 145: "Scrolllock"
1277 },
1278
1279 PRINTABLE_KEYS: {
1280 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5',
1281 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a',
1282 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h',
1283 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',
1284 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
1285 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
1286 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',
1287 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*'
1288 }
1289 };
1290 var name, i;
1291 for (i in ret.FUNCTION_KEYS) {
1292 name = ret.FUNCTION_KEYS[i].toLowerCase();
1293 ret[name] = parseInt(i, 10);
1294 }
1295 for (i in ret.PRINTABLE_KEYS) {
1296 name = ret.PRINTABLE_KEYS[i].toLowerCase();
1297 ret[name] = parseInt(i, 10);
1298 }
1299 oop.mixin(ret, ret.MODIFIER_KEYS);
1300 oop.mixin(ret, ret.PRINTABLE_KEYS);
1301 oop.mixin(ret, ret.FUNCTION_KEYS);
1302 ret.enter = ret["return"];
1303 ret.escape = ret.esc;
1304 ret.del = ret["delete"];
1305 ret[173] = '-';
1306
1307 (function() {
1308 var mods = ["cmd", "ctrl", "alt", "shift"];
1309 for (var i = Math.pow(2, mods.length); i--;) {
1310 ret.KEY_MODS[i] = mods.filter(function(x) {
1311 return i & ret.KEY_MODS[x];
1312 }).join("-") + "-";
1313 }
1314 })();
1315
1316 ret.KEY_MODS[0] = "";
1317 ret.KEY_MODS[-1] = "input-";
1318
1319 return ret;
1320 })();
1321 oop.mixin(exports, Keys);
1322
1323 exports.keyCodeToString = function(keyCode) {
1324 var keyString = Keys[keyCode];
1325 if (typeof keyString != "string")
1326 keyString = String.fromCharCode(keyCode);
1327 return keyString.toLowerCase();
1328 };
1329
1330 });
1331
1332 define("ace/lib/useragent",["require","exports","module"], function(require, exports, module) {
1333 "use strict";
1334 exports.OS = {
1335 LINUX: "LINUX",
1336 MAC: "MAC",
1337 WINDOWS: "WINDOWS"
1338 };
1339 exports.getOS = function() {
1340 if (exports.isMac) {
1341 return exports.OS.MAC;
1342 } else if (exports.isLinux) {
1343 return exports.OS.LINUX;
1344 } else {
1345 return exports.OS.WINDOWS;
1346 }
1347 };
1348 if (typeof navigator != "object")
1349 return;
1350
1351 var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
1352 var ua = navigator.userAgent;
1353 exports.isWin = (os == "win");
1354 exports.isMac = (os == "mac");
1355 exports.isLinux = (os == "linux");
1356 exports.isIE =
1357 (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
1358 ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1])
1359 : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie
1360
1361 exports.isOldIE = exports.isIE && exports.isIE < 9;
1362 exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko";
1363 exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv:(\d+)/)||[])[1], 10) < 4;
1364 exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
1365 exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
1366
1367 exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
1368
1369 exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
1370
1371 exports.isIPad = ua.indexOf("iPad") >= 0;
1372
1373 exports.isChromeOS = ua.indexOf(" CrOS ") >= 0;
1374
1375 exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
1376
1377 if (exports.isIOS) exports.isMac = true;
1378
1379 });
1380
1381 define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) {
1382 "use strict";
1383
1384 var keys = require("./keys");
1385 var useragent = require("./useragent");
1386
1387 var pressedKeys = null;
1388 var ts = 0;
1389
1390 exports.addListener = function(elem, type, callback) {
1391 if (elem.addEventListener) {
1392 return elem.addEventListener(type, callback, false);
1393 }
1394 if (elem.attachEvent) {
1395 var wrapper = function() {
1396 callback.call(elem, window.event);
1397 };
1398 callback._wrapper = wrapper;
1399 elem.attachEvent("on" + type, wrapper);
1400 }
1401 };
1402
1403 exports.removeListener = function(elem, type, callback) {
1404 if (elem.removeEventListener) {
1405 return elem.removeEventListener(type, callback, false);
1406 }
1407 if (elem.detachEvent) {
1408 elem.detachEvent("on" + type, callback._wrapper || callback);
1409 }
1410 };
1411 exports.stopEvent = function(e) {
1412 exports.stopPropagation(e);
1413 exports.preventDefault(e);
1414 return false;
1415 };
1416
1417 exports.stopPropagation = function(e) {
1418 if (e.stopPropagation)
1419 e.stopPropagation();
1420 else
1421 e.cancelBubble = true;
1422 };
1423
1424 exports.preventDefault = function(e) {
1425 if (e.preventDefault)
1426 e.preventDefault();
1427 else
1428 e.returnValue = false;
1429 };
1430 exports.getButton = function(e) {
1431 if (e.type == "dblclick")
1432 return 0;
1433 if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
1434 return 2;
1435 if (e.preventDefault) {
1436 return e.button;
1437 }
1438 else {
1439 return {1:0, 2:2, 4:1}[e.button];
1440 }
1441 };
1442
1443 exports.capture = function(el, eventHandler, releaseCaptureHandler) {
1444 function onMouseUp(e) {
1445 eventHandler && eventHandler(e);
1446 releaseCaptureHandler && releaseCaptureHandler(e);
1447
1448 exports.removeListener(document, "mousemove", eventHandler, true);
1449 exports.removeListener(document, "mouseup", onMouseUp, true);
1450 exports.removeListener(document, "dragstart", onMouseUp, true);
1451 }
1452
1453 exports.addListener(document, "mousemove", eventHandler, true);
1454 exports.addListener(document, "mouseup", onMouseUp, true);
1455 exports.addListener(document, "dragstart", onMouseUp, true);
1456
1457 return onMouseUp;
1458 };
1459
1460 exports.addTouchMoveListener = function (el, callback) {
1461 var startx, starty;
1462 exports.addListener(el, "touchstart", function (e) {
1463 var touches = e.touches;
1464 var touchObj = touches[0];
1465 startx = touchObj.clientX;
1466 starty = touchObj.clientY;
1467 });
1468 exports.addListener(el, "touchmove", function (e) {
1469 var touches = e.touches;
1470 if (touches.length > 1) return;
1471
1472 var touchObj = touches[0];
1473
1474 e.wheelX = startx - touchObj.clientX;
1475 e.wheelY = starty - touchObj.clientY;
1476
1477 startx = touchObj.clientX;
1478 starty = touchObj.clientY;
1479
1480 callback(e);
1481 });
1482 };
1483
1484 exports.addMouseWheelListener = function(el, callback) {
1485 if ("onmousewheel" in el) {
1486 exports.addListener(el, "mousewheel", function(e) {
1487 var factor = 8;
1488 if (e.wheelDeltaX !== undefined) {
1489 e.wheelX = -e.wheelDeltaX / factor;
1490 e.wheelY = -e.wheelDeltaY / factor;
1491 } else {
1492 e.wheelX = 0;
1493 e.wheelY = -e.wheelDelta / factor;
1494 }
1495 callback(e);
1496 });
1497 } else if ("onwheel" in el) {
1498 exports.addListener(el, "wheel", function(e) {
1499 var factor = 0.35;
1500 switch (e.deltaMode) {
1501 case e.DOM_DELTA_PIXEL:
1502 e.wheelX = e.deltaX * factor || 0;
1503 e.wheelY = e.deltaY * factor || 0;
1504 break;
1505 case e.DOM_DELTA_LINE:
1506 case e.DOM_DELTA_PAGE:
1507 e.wheelX = (e.deltaX || 0) * 5;
1508 e.wheelY = (e.deltaY || 0) * 5;
1509 break;
1510 }
1511
1512 callback(e);
1513 });
1514 } else {
1515 exports.addListener(el, "DOMMouseScroll", function(e) {
1516 if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
1517 e.wheelX = (e.detail || 0) * 5;
1518 e.wheelY = 0;
1519 } else {
1520 e.wheelX = 0;
1521 e.wheelY = (e.detail || 0) * 5;
1522 }
1523 callback(e);
1524 });
1525 }
1526 };
1527
1528 exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName) {
1529 var clicks = 0;
1530 var startX, startY, timer;
1531 var eventNames = {
1532 2: "dblclick",
1533 3: "tripleclick",
1534 4: "quadclick"
1535 };
1536
1537 function onMousedown(e) {
1538 if (exports.getButton(e) !== 0) {
1539 clicks = 0;
1540 } else if (e.detail > 1) {
1541 clicks++;
1542 if (clicks > 4)
1543 clicks = 1;
1544 } else {
1545 clicks = 1;
1546 }
1547 if (useragent.isIE) {
1548 var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
1549 if (!timer || isNewClick)
1550 clicks = 1;
1551 if (timer)
1552 clearTimeout(timer);
1553 timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
1554
1555 if (clicks == 1) {
1556 startX = e.clientX;
1557 startY = e.clientY;
1558 }
1559 }
1560
1561 e._clicks = clicks;
1562
1563 eventHandler[callbackName]("mousedown", e);
1564
1565 if (clicks > 4)
1566 clicks = 0;
1567 else if (clicks > 1)
1568 return eventHandler[callbackName](eventNames[clicks], e);
1569 }
1570 function onDblclick(e) {
1571 clicks = 2;
1572 if (timer)
1573 clearTimeout(timer);
1574 timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
1575 eventHandler[callbackName]("mousedown", e);
1576 eventHandler[callbackName](eventNames[clicks], e);
1577 }
1578 if (!Array.isArray(elements))
1579 elements = [elements];
1580 elements.forEach(function(el) {
1581 exports.addListener(el, "mousedown", onMousedown);
1582 if (useragent.isOldIE)
1583 exports.addListener(el, "dblclick", onDblclick);
1584 });
1585 };
1586
1587 var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window)
1588 ? function(e) {
1589 return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
1590 }
1591 : function(e) {
1592 return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
1593 };
1594
1595 exports.getModifierString = function(e) {
1596 return keys.KEY_MODS[getModifierHash(e)];
1597 };
1598
1599 function normalizeCommandKeys(callback, e, keyCode) {
1600 var hashId = getModifierHash(e);
1601
1602 if (!useragent.isMac && pressedKeys) {
1603 if (e.getModifierState && (e.getModifierState("OS") || e.getModifierState("Win")))
1604 hashId |= 8;
1605 if (pressedKeys.altGr) {
1606 if ((3 & hashId) != 3)
1607 pressedKeys.altGr = 0;
1608 else
1609 return;
1610 }
1611 if (keyCode === 18 || keyCode === 17) {
1612 var location = "location" in e ? e.location : e.keyLocation;
1613 if (keyCode === 17 && location === 1) {
1614 if (pressedKeys[keyCode] == 1)
1615 ts = e.timeStamp;
1616 } else if (keyCode === 18 && hashId === 3 && location === 2) {
1617 var dt = e.timeStamp - ts;
1618 if (dt < 50)
1619 pressedKeys.altGr = true;
1620 }
1621 }
1622 }
1623
1624 if (keyCode in keys.MODIFIER_KEYS) {
1625 keyCode = -1;
1626 }
1627 if (hashId & 8 && (keyCode >= 91 && keyCode <= 93)) {
1628 keyCode = -1;
1629 }
1630
1631 if (!hashId && keyCode === 13) {
1632 var location = "location" in e ? e.location : e.keyLocation;
1633 if (location === 3) {
1634 callback(e, hashId, -keyCode);
1635 if (e.defaultPrevented)
1636 return;
1637 }
1638 }
1639
1640 if (useragent.isChromeOS && hashId & 8) {
1641 callback(e, hashId, keyCode);
1642 if (e.defaultPrevented)
1643 return;
1644 else
1645 hashId &= ~8;
1646 }
1647 if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
1648 return false;
1649 }
1650
1651 return callback(e, hashId, keyCode);
1652 }
1653
1654
1655 exports.addCommandKeyListener = function(el, callback) {
1656 var addListener = exports.addListener;
1657 if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
1658 var lastKeyDownKeyCode = null;
1659 addListener(el, "keydown", function(e) {
1660 lastKeyDownKeyCode = e.keyCode;
1661 });
1662 addListener(el, "keypress", function(e) {
1663 return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);
1664 });
1665 } else {
1666 var lastDefaultPrevented = null;
1667
1668 addListener(el, "keydown", function(e) {
1669 pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1;
1670 var result = normalizeCommandKeys(callback, e, e.keyCode);
1671 lastDefaultPrevented = e.defaultPrevented;
1672 return result;
1673 });
1674
1675 addListener(el, "keypress", function(e) {
1676 if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {
1677 exports.stopEvent(e);
1678 lastDefaultPrevented = null;
1679 }
1680 });
1681
1682 addListener(el, "keyup", function(e) {
1683 pressedKeys[e.keyCode] = null;
1684 });
1685
1686 if (!pressedKeys) {
1687 resetPressedKeys();
1688 addListener(window, "focus", resetPressedKeys);
1689 }
1690 }
1691 };
1692 function resetPressedKeys() {
1693 pressedKeys = Object.create(null);
1694 }
1695
1696 if (typeof window == "object" && window.postMessage && !useragent.isOldIE) {
1697 var postMessageId = 1;
1698 exports.nextTick = function(callback, win) {
1699 win = win || window;
1700 var messageName = "zero-timeout-message-" + postMessageId;
1701 exports.addListener(win, "message", function listener(e) {
1702 if (e.data == messageName) {
1703 exports.stopPropagation(e);
1704 exports.removeListener(win, "message", listener);
1705 callback();
1706 }
1707 });
1708 win.postMessage(messageName, "*");
1709 };
1710 }
1711
1712
1713 exports.nextFrame = typeof window == "object" && (window.requestAnimationFrame
1714 || window.mozRequestAnimationFrame
1715 || window.webkitRequestAnimationFrame
1716 || window.msRequestAnimationFrame
1717 || window.oRequestAnimationFrame);
1718
1719 if (exports.nextFrame)
1720 exports.nextFrame = exports.nextFrame.bind(window);
1721 else
1722 exports.nextFrame = function(callback) {
1723 setTimeout(callback, 17);
1724 };
1725 });
1726
1727 define("ace/lib/lang",["require","exports","module"], function(require, exports, module) {
1728 "use strict";
1729
1730 exports.last = function(a) {
1731 return a[a.length - 1];
1732 };
1733
1734 exports.stringReverse = function(string) {
1735 return string.split("").reverse().join("");
1736 };
1737
1738 exports.stringRepeat = function (string, count) {
1739 var result = '';
1740 while (count > 0) {
1741 if (count & 1)
1742 result += string;
1743
1744 if (count >>= 1)
1745 string += string;
1746 }
1747 return result;
1748 };
1749
1750 var trimBeginRegexp = /^\s\s*/;
1751 var trimEndRegexp = /\s\s*$/;
1752
1753 exports.stringTrimLeft = function (string) {
1754 return string.replace(trimBeginRegexp, '');
1755 };
1756
1757 exports.stringTrimRight = function (string) {
1758 return string.replace(trimEndRegexp, '');
1759 };
1760
1761 exports.copyObject = function(obj) {
1762 var copy = {};
1763 for (var key in obj) {
1764 copy[key] = obj[key];
1765 }
1766 return copy;
1767 };
1768
1769 exports.copyArray = function(array){
1770 var copy = [];
1771 for (var i=0, l=array.length; i<l; i++) {
1772 if (array[i] && typeof array[i] == "object")
1773 copy[i] = this.copyObject(array[i]);
1774 else
1775 copy[i] = array[i];
1776 }
1777 return copy;
1778 };
1779
1780 exports.deepCopy = function deepCopy(obj) {
1781 if (typeof obj !== "object" || !obj)
1782 return obj;
1783 var copy;
1784 if (Array.isArray(obj)) {
1785 copy = [];
1786 for (var key = 0; key < obj.length; key++) {
1787 copy[key] = deepCopy(obj[key]);
1788 }
1789 return copy;
1790 }
1791 if (Object.prototype.toString.call(obj) !== "[object Object]")
1792 return obj;
1793
1794 copy = {};
1795 for (var key in obj)
1796 copy[key] = deepCopy(obj[key]);
1797 return copy;
1798 };
1799
1800 exports.arrayToMap = function(arr) {
1801 var map = {};
1802 for (var i=0; i<arr.length; i++) {
1803 map[arr[i]] = 1;
1804 }
1805 return map;
1806
1807 };
1808
1809 exports.createMap = function(props) {
1810 var map = Object.create(null);
1811 for (var i in props) {
1812 map[i] = props[i];
1813 }
1814 return map;
1815 };
1816 exports.arrayRemove = function(array, value) {
1817 for (var i = 0; i <= array.length; i++) {
1818 if (value === array[i]) {
1819 array.splice(i, 1);
1820 }
1821 }
1822 };
1823
1824 exports.escapeRegExp = function(str) {
1825 return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1826 };
1827
1828 exports.escapeHTML = function(str) {
1829 return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
1830 };
1831
1832 exports.getMatchOffsets = function(string, regExp) {
1833 var matches = [];
1834
1835 string.replace(regExp, function(str) {
1836 matches.push({
1837 offset: arguments[arguments.length-2],
1838 length: str.length
1839 });
1840 });
1841
1842 return matches;
1843 };
1844 exports.deferredCall = function(fcn) {
1845 var timer = null;
1846 var callback = function() {
1847 timer = null;
1848 fcn();
1849 };
1850
1851 var deferred = function(timeout) {
1852 deferred.cancel();
1853 timer = setTimeout(callback, timeout || 0);
1854 return deferred;
1855 };
1856
1857 deferred.schedule = deferred;
1858
1859 deferred.call = function() {
1860 this.cancel();
1861 fcn();
1862 return deferred;
1863 };
1864
1865 deferred.cancel = function() {
1866 clearTimeout(timer);
1867 timer = null;
1868 return deferred;
1869 };
1870
1871 deferred.isPending = function() {
1872 return timer;
1873 };
1874
1875 return deferred;
1876 };
1877
1878
1879 exports.delayedCall = function(fcn, defaultTimeout) {
1880 var timer = null;
1881 var callback = function() {
1882 timer = null;
1883 fcn();
1884 };
1885
1886 var _self = function(timeout) {
1887 if (timer == null)
1888 timer = setTimeout(callback, timeout || defaultTimeout);
1889 };
1890
1891 _self.delay = function(timeout) {
1892 timer && clearTimeout(timer);
1893 timer = setTimeout(callback, timeout || defaultTimeout);
1894 };
1895 _self.schedule = _self;
1896
1897 _self.call = function() {
1898 this.cancel();
1899 fcn();
1900 };
1901
1902 _self.cancel = function() {
1903 timer && clearTimeout(timer);
1904 timer = null;
1905 };
1906
1907 _self.isPending = function() {
1908 return timer;
1909 };
1910
1911 return _self;
1912 };
1913 });
1914
1915 define("ace/keyboard/textinput_ios",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/lib/keys"], function(require, exports, module) {
1916 "use strict";
1917
1918 var event = require("../lib/event");
1919 var useragent = require("../lib/useragent");
1920 var dom = require("../lib/dom");
1921 var lang = require("../lib/lang");
1922 var KEYS = require("../lib/keys");
1923 var MODS = KEYS.KEY_MODS;
1924 var BROKEN_SETDATA = useragent.isChrome < 18;
1925 var USE_IE_MIME_TYPE = useragent.isIE;
1926
1927 var TextInput = function(parentNode, host) {
1928 var self = this;
1929 var text = dom.createElement("textarea");
1930 text.className = useragent.isIOS ? "ace_text-input ace_text-input-ios" : "ace_text-input";
1931
1932 if (useragent.isTouchPad)
1933 text.setAttribute("x-palm-disable-auto-cap", true);
1934
1935 text.setAttribute("wrap", "off");
1936 text.setAttribute("autocorrect", "off");
1937 text.setAttribute("autocapitalize", "off");
1938 text.setAttribute("spellcheck", false);
1939
1940 text.style.opacity = "0";
1941 parentNode.insertBefore(text, parentNode.firstChild);
1942
1943 var PLACEHOLDER = "\n aaaa a\n";
1944
1945 var copied = false;
1946 var cut = false;
1947 var pasted = false;
1948 var inComposition = false;
1949 var tempStyle = '';
1950 var isSelectionEmpty = true;
1951 try { var isFocused = document.activeElement === text; } catch(e) {}
1952
1953 event.addListener(text, "blur", function(e) {
1954 host.onBlur(e);
1955 isFocused = false;
1956 });
1957 event.addListener(text, "focus", function(e) {
1958 isFocused = true;
1959 host.onFocus(e);
1960 resetSelection();
1961 });
1962 this.focus = function() {
1963 if (tempStyle) return text.focus();
1964 text.style.position = "fixed";
1965 text.focus();
1966 };
1967 this.blur = function() {
1968 text.blur();
1969 };
1970 this.isFocused = function() {
1971 return isFocused;
1972 };
1973 var syncSelection = lang.delayedCall(function() {
1974 isFocused && resetSelection(isSelectionEmpty);
1975 });
1976 var syncValue = lang.delayedCall(function() {
1977 if (!inComposition) {
1978 text.value = PLACEHOLDER;
1979 isFocused && resetSelection();
1980 }
1981 });
1982
1983 function resetSelection(isEmpty) {
1984 if (inComposition)
1985 return;
1986 inComposition = true;
1987
1988 if (inputHandler) {
1989 selectionStart = 0;
1990 selectionEnd = isEmpty ? 0 : text.value.length - 1;
1991 } else {
1992 var selectionStart = 4;
1993 var selectionEnd = 5;
1994 }
1995 try {
1996 text.setSelectionRange(selectionStart, selectionEnd);
1997 } catch(e) {}
1998
1999 inComposition = false;
2000 }
2001
2002 function resetValue() {
2003 if (inComposition)
2004 return;
2005 text.value = PLACEHOLDER;
2006 if (useragent.isWebKit)
2007 syncValue.schedule();
2008 }
2009
2010 useragent.isWebKit || host.addEventListener('changeSelection', function() {
2011 if (host.selection.isEmpty() != isSelectionEmpty) {
2012 isSelectionEmpty = !isSelectionEmpty;
2013 syncSelection.schedule();
2014 }
2015 });
2016
2017 resetValue();
2018 if (isFocused)
2019 host.onFocus();
2020
2021
2022 var isAllSelected = function(text) {
2023 return text.selectionStart === 0 && text.selectionEnd === text.value.length;
2024 };
2025
2026 var onSelect = function(e) {
2027 if (isAllSelected(text)) {
2028 host.selectAll();
2029 resetSelection();
2030 } else if (inputHandler) {
2031 resetSelection(host.selection.isEmpty());
2032 }
2033 };
2034
2035 var inputHandler = null;
2036 this.setInputHandler = function(cb) {inputHandler = cb;};
2037 this.getInputHandler = function() {return inputHandler;};
2038 var afterContextMenu = false;
2039
2040 var sendText = function(data) {
2041 if (text.selectionStart === 4 && text.selectionEnd === 5) {
2042 return;
2043 }
2044 if (inputHandler) {
2045 data = inputHandler(data);
2046 inputHandler = null;
2047 }
2048 if (pasted) {
2049 resetSelection();
2050 if (data)
2051 host.onPaste(data);
2052 pasted = false;
2053 } else if (data == PLACEHOLDER.substr(0) && text.selectionStart === 4) {
2054 if (afterContextMenu)
2055 host.execCommand("del", {source: "ace"});
2056 else // some versions of android do not fire keydown when pressing backspace
2057 host.execCommand("backspace", {source: "ace"});
2058 } else if (!copied) {
2059 if (data.substring(0, 9) == PLACEHOLDER && data.length > PLACEHOLDER.length)
2060 data = data.substr(9);
2061 else if (data.substr(0, 4) == PLACEHOLDER.substr(0, 4))
2062 data = data.substr(4, data.length - PLACEHOLDER.length + 1);
2063 else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2064 data = data.slice(0, -1);
2065 if (data == PLACEHOLDER.charAt(0)) {
2066 } else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2067 data = data.slice(0, -1);
2068
2069 if (data)
2070 host.onTextInput(data);
2071 }
2072 if (copied) {
2073 copied = false;
2074 }
2075 if (afterContextMenu)
2076 afterContextMenu = false;
2077 };
2078 var onInput = function(e) {
2079 if (inComposition)
2080 return;
2081 var data = text.value;
2082 sendText(data);
2083 resetValue();
2084 };
2085
2086 var handleClipboardData = function(e, data, forceIEMime) {
2087 var clipboardData = e.clipboardData || window.clipboardData;
2088 if (!clipboardData || BROKEN_SETDATA)
2089 return;
2090 var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain";
2091 try {
2092 if (data) {
2093 return clipboardData.setData(mime, data) !== false;
2094 } else {
2095 return clipboardData.getData(mime);
2096 }
2097 } catch(e) {
2098 if (!forceIEMime)
2099 return handleClipboardData(e, data, true);
2100 }
2101 };
2102
2103 var doCopy = function(e, isCut) {
2104 var data = host.getCopyText();
2105 if (!data)
2106 return event.preventDefault(e);
2107
2108 if (handleClipboardData(e, data)) {
2109 if (useragent.isIOS) {
2110 cut = isCut;
2111 text.value = "\n aa" + data + "a a\n";
2112 text.setSelectionRange(4, 4 + data.length);
2113 copied = {
2114 value: data
2115 };
2116 }
2117 isCut ? host.onCut() : host.onCopy();
2118 if (!useragent.isIOS) event.preventDefault(e);
2119 } else {
2120 copied = true;
2121 text.value = data;
2122 text.select();
2123 setTimeout(function(){
2124 copied = false;
2125 resetValue();
2126 resetSelection();
2127 isCut ? host.onCut() : host.onCopy();
2128 });
2129 }
2130 };
2131
2132 var onCut = function(e) {
2133 doCopy(e, true);
2134 };
2135
2136 var onCopy = function(e) {
2137 doCopy(e, false);
2138 };
2139
2140 var onPaste = function(e) {
2141 var data = handleClipboardData(e);
2142 if (typeof data == "string") {
2143 if (data)
2144 host.onPaste(data, e);
2145 if (useragent.isIE)
2146 setTimeout(resetSelection);
2147 event.preventDefault(e);
2148 }
2149 else {
2150 text.value = "";
2151 pasted = true;
2152 }
2153 };
2154
2155 event.addCommandKeyListener(text, host.onCommandKey.bind(host));
2156
2157 event.addListener(text, "select", onSelect);
2158
2159 event.addListener(text, "input", onInput);
2160
2161 event.addListener(text, "cut", onCut);
2162 event.addListener(text, "copy", onCopy);
2163 event.addListener(text, "paste", onPaste);
2164 var onCompositionStart = function(e) {
2165 if (inComposition || !host.onCompositionStart || host.$readOnly)
2166 return;
2167 inComposition = {};
2168 inComposition.canUndo = host.session.$undoManager;
2169 host.onCompositionStart();
2170 setTimeout(onCompositionUpdate, 0);
2171 host.on("mousedown", onCompositionEnd);
2172 if (inComposition.canUndo && !host.selection.isEmpty()) {
2173 host.insert("");
2174 host.session.markUndoGroup();
2175 host.selection.clearSelection();
2176 }
2177 host.session.markUndoGroup();
2178 };
2179
2180 var onCompositionUpdate = function() {
2181 if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
2182 return;
2183 var val = text.value.replace(/\x01/g, "");
2184 if (inComposition.lastValue === val) return;
2185
2186 host.onCompositionUpdate(val);
2187 if (inComposition.lastValue)
2188 host.undo();
2189 if (inComposition.canUndo)
2190 inComposition.lastValue = val;
2191 if (inComposition.lastValue) {
2192 var r = host.selection.getRange();
2193 host.insert(inComposition.lastValue);
2194 host.session.markUndoGroup();
2195 inComposition.range = host.selection.getRange();
2196 host.selection.setRange(r);
2197 host.selection.clearSelection();
2198 }
2199 };
2200
2201 var onCompositionEnd = function(e) {
2202 if (!host.onCompositionEnd || host.$readOnly) return;
2203 var c = inComposition;
2204 inComposition = false;
2205 var timer = setTimeout(function() {
2206 timer = null;
2207 var str = text.value.replace(/\x01/g, "");
2208 if (inComposition)
2209 return;
2210 else if (str == c.lastValue)
2211 resetValue();
2212 else if (!c.lastValue && str) {
2213 resetValue();
2214 sendText(str);
2215 }
2216 });
2217 inputHandler = function compositionInputHandler(str) {
2218 if (timer)
2219 clearTimeout(timer);
2220 str = str.replace(/\x01/g, "");
2221 if (str == c.lastValue)
2222 return "";
2223 if (c.lastValue && timer)
2224 host.undo();
2225 return str;
2226 };
2227 host.onCompositionEnd();
2228 host.removeListener("mousedown", onCompositionEnd);
2229 if (e.type == "compositionend" && c.range) {
2230 host.selection.setRange(c.range);
2231 }
2232 var needsOnInput =
2233 (!!useragent.isChrome && useragent.isChrome >= 53) ||
2234 (!!useragent.isWebKit && useragent.isWebKit >= 603);
2235
2236 if (needsOnInput) {
2237 onInput();
2238 }
2239 };
2240
2241
2242
2243 var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
2244
2245 event.addListener(text, "compositionstart", onCompositionStart);
2246 if (useragent.isGecko) {
2247 event.addListener(text, "text", function(){syncComposition.schedule();});
2248 } else {
2249 event.addListener(text, "keyup", function(){syncComposition.schedule();});
2250 event.addListener(text, "keydown", function(){syncComposition.schedule();});
2251 }
2252 event.addListener(text, "compositionend", onCompositionEnd);
2253
2254 this.getElement = function() {
2255 return text;
2256 };
2257
2258 this.setReadOnly = function(readOnly) {
2259 text.readOnly = readOnly;
2260 };
2261
2262 this.onContextMenu = function(e) {
2263 afterContextMenu = true;
2264 resetSelection(host.selection.isEmpty());
2265 host._emit("nativecontextmenu", {target: host, domEvent: e});
2266 this.moveToMouse(e, true);
2267 };
2268
2269 this.moveToMouse = function(e, bringToFront) {
2270 if (!tempStyle)
2271 tempStyle = text.style.cssText;
2272 text.style.cssText = (bringToFront ? "z-index:100000;" : "")
2273 + "height:" + text.style.height + ";"
2274 + (useragent.isIE ? "opacity:0.1;" : "");
2275
2276 var rect = host.container.getBoundingClientRect();
2277 var style = dom.computedStyle(host.container);
2278 var top = rect.top + (parseInt(style.borderTopWidth) || 0);
2279 var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
2280 var maxTop = rect.bottom - top - text.clientHeight -2;
2281 var move = function(e) {
2282 text.style.left = e.clientX - left - 2 + "px";
2283 text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
2284 };
2285 move(e);
2286
2287 if (e.type != "mousedown")
2288 return;
2289
2290 if (host.renderer.$keepTextAreaAtCursor)
2291 host.renderer.$keepTextAreaAtCursor = null;
2292
2293 clearTimeout(closeTimeout);
2294 if (useragent.isWin)
2295 event.capture(host.container, move, onContextMenuClose);
2296 };
2297
2298 this.onContextMenuClose = onContextMenuClose;
2299 var closeTimeout;
2300 function onContextMenuClose() {
2301 clearTimeout(closeTimeout);
2302 closeTimeout = setTimeout(function () {
2303 if (tempStyle) {
2304 text.style.cssText = tempStyle;
2305 tempStyle = '';
2306 }
2307 if (host.renderer.$keepTextAreaAtCursor == null) {
2308 host.renderer.$keepTextAreaAtCursor = true;
2309 host.renderer.$moveTextAreaToCursor();
2310 }
2311 }, 0);
2312 }
2313
2314 var onContextMenu = function(e) {
2315 host.textInput.onContextMenu(e);
2316 onContextMenuClose();
2317 };
2318 event.addListener(text, "mouseup", onContextMenu);
2319 event.addListener(text, "mousedown", function(e) {
2320 e.preventDefault();
2321 onContextMenuClose();
2322 });
2323 event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
2324 event.addListener(text, "contextmenu", onContextMenu);
2325
2326 if (useragent.isIOS) {
2327 var typingResetTimeout = null;
2328 var typing = false;
2329
2330 parentNode.addEventListener("keydown", function (e) {
2331 if (typingResetTimeout) clearTimeout(typingResetTimeout);
2332 typing = true;
2333 });
2334
2335 parentNode.addEventListener("keyup", function (e) {
2336 typingResetTimeout = setTimeout(function () {
2337 typing = false;
2338 }, 100);
2339 });
2340 var detectArrowKeys = function(e) {
2341 if (document.activeElement !== text) return;
2342 if (typing) return;
2343
2344 if (cut) {
2345 return setTimeout(function () {
2346 cut = false;
2347 }, 100);
2348 }
2349 var selectionStart = text.selectionStart;
2350 var selectionEnd = text.selectionEnd;
2351 text.setSelectionRange(4, 5);
2352 if (selectionStart == selectionEnd) {
2353 switch (selectionStart) {
2354 case 0: host.onCommandKey(null, 0, KEYS.up); break;
2355 case 1: host.onCommandKey(null, 0, KEYS.home); break;
2356 case 2: host.onCommandKey(null, MODS.option, KEYS.left); break;
2357 case 4: host.onCommandKey(null, 0, KEYS.left); break;
2358 case 5: host.onCommandKey(null, 0, KEYS.right); break;
2359 case 7: host.onCommandKey(null, MODS.option, KEYS.right); break;
2360 case 8: host.onCommandKey(null, 0, KEYS.end); break;
2361 case 9: host.onCommandKey(null, 0, KEYS.down); break;
2362 }
2363 } else {
2364 switch (selectionEnd) {
2365 case 6: host.onCommandKey(null, MODS.shift, KEYS.right); break;
2366 case 7: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.right); break;
2367 case 8: host.onCommandKey(null, MODS.shift, KEYS.end); break;
2368 case 9: host.onCommandKey(null, MODS.shift, KEYS.down); break;
2369 }
2370 switch (selectionStart) {
2371 case 0: host.onCommandKey(null, MODS.shift, KEYS.up); break;
2372 case 1: host.onCommandKey(null, MODS.shift, KEYS.home); break;
2373 case 2: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.left); break;
2374 case 3: host.onCommandKey(null, MODS.shift, KEYS.left); break;
2375 }
2376 }
2377 };
2378 document.addEventListener("selectionchange", detectArrowKeys);
2379 host.on("destroy", function() {
2380 document.removeEventListener("selectionchange", detectArrowKeys);
2381 });
2382 }
2383 };
2384
2385 exports.TextInput = TextInput;
2386 });
2387
2388 define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/keyboard/textinput_ios"], function(require, exports, module) {
2389 "use strict";
2390
2391 var event = require("../lib/event");
2392 var useragent = require("../lib/useragent");
2393 var dom = require("../lib/dom");
2394 var lang = require("../lib/lang");
2395 var BROKEN_SETDATA = useragent.isChrome < 18;
2396 var USE_IE_MIME_TYPE = useragent.isIE;
2397
2398 var TextInputIOS = require("./textinput_ios").TextInput;
2399 var TextInput = function(parentNode, host) {
2400 if (useragent.isIOS)
2401 return TextInputIOS.call(this, parentNode, host);
2402
2403 var text = dom.createElement("textarea");
2404 text.className = "ace_text-input";
2405
2406 text.setAttribute("wrap", "off");
2407 text.setAttribute("autocorrect", "off");
2408 text.setAttribute("autocapitalize", "off");
2409 text.setAttribute("spellcheck", false);
2410
2411 text.style.opacity = "0";
2412 parentNode.insertBefore(text, parentNode.firstChild);
2413
2414 var PLACEHOLDER = "\u2028\u2028";
2415
2416 var copied = false;
2417 var pasted = false;
2418 var inComposition = false;
2419 var tempStyle = '';
2420 var isSelectionEmpty = true;
2421 try { var isFocused = document.activeElement === text; } catch(e) {}
2422
2423 event.addListener(text, "blur", function(e) {
2424 host.onBlur(e);
2425 isFocused = false;
2426 });
2427 event.addListener(text, "focus", function(e) {
2428 isFocused = true;
2429 host.onFocus(e);
2430 resetSelection();
2431 });
2432 this.focus = function() {
2433 if (tempStyle) return text.focus();
2434 var top = text.style.top;
2435 text.style.position = "fixed";
2436 text.style.top = "0px";
2437 text.focus();
2438 setTimeout(function() {
2439 text.style.position = "";
2440 if (text.style.top == "0px")
2441 text.style.top = top;
2442 }, 0);
2443 };
2444 this.blur = function() {
2445 text.blur();
2446 };
2447 this.isFocused = function() {
2448 return isFocused;
2449 };
2450 var syncSelection = lang.delayedCall(function() {
2451 isFocused && resetSelection(isSelectionEmpty);
2452 });
2453 var syncValue = lang.delayedCall(function() {
2454 if (!inComposition) {
2455 text.value = PLACEHOLDER;
2456 isFocused && resetSelection();
2457 }
2458 });
2459
2460 function resetSelection(isEmpty) {
2461 if (inComposition)
2462 return;
2463 inComposition = true;
2464
2465 if (inputHandler) {
2466 var selectionStart = 0;
2467 var selectionEnd = isEmpty ? 0 : text.value.length - 1;
2468 } else {
2469 var selectionStart = isEmpty ? 2 : 1;
2470 var selectionEnd = 2;
2471 }
2472 try {
2473 text.setSelectionRange(selectionStart, selectionEnd);
2474 } catch(e){}
2475
2476 inComposition = false;
2477 }
2478
2479 function resetValue() {
2480 if (inComposition)
2481 return;
2482 text.value = PLACEHOLDER;
2483 if (useragent.isWebKit)
2484 syncValue.schedule();
2485 }
2486
2487 useragent.isWebKit || host.addEventListener('changeSelection', function() {
2488 if (host.selection.isEmpty() != isSelectionEmpty) {
2489 isSelectionEmpty = !isSelectionEmpty;
2490 syncSelection.schedule();
2491 }
2492 });
2493
2494 resetValue();
2495 if (isFocused)
2496 host.onFocus();
2497
2498
2499 var isAllSelected = function(text) {
2500 return text.selectionStart === 0 && text.selectionEnd === text.value.length;
2501 };
2502
2503 var onSelect = function(e) {
2504 if (copied) {
2505 copied = false;
2506 } else if (isAllSelected(text)) {
2507 host.selectAll();
2508 resetSelection();
2509 } else if (inputHandler) {
2510 resetSelection(host.selection.isEmpty());
2511 }
2512 };
2513
2514 var inputHandler = null;
2515 this.setInputHandler = function(cb) {inputHandler = cb;};
2516 this.getInputHandler = function() {return inputHandler;};
2517 var afterContextMenu = false;
2518
2519 var sendText = function(data) {
2520 if (inputHandler) {
2521 data = inputHandler(data);
2522 inputHandler = null;
2523 }
2524 if (pasted) {
2525 resetSelection();
2526 if (data)
2527 host.onPaste(data);
2528 pasted = false;
2529 } else if (data == PLACEHOLDER.charAt(0)) {
2530 if (afterContextMenu)
2531 host.execCommand("del", {source: "ace"});
2532 else // some versions of android do not fire keydown when pressing backspace
2533 host.execCommand("backspace", {source: "ace"});
2534 } else {
2535 if (data.substring(0, 2) == PLACEHOLDER)
2536 data = data.substr(2);
2537 else if (data.charAt(0) == PLACEHOLDER.charAt(0))
2538 data = data.substr(1);
2539 else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2540 data = data.slice(0, -1);
2541 if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
2542 data = data.slice(0, -1);
2543
2544 if (data)
2545 host.onTextInput(data);
2546 }
2547 if (afterContextMenu)
2548 afterContextMenu = false;
2549 };
2550 var onInput = function(e) {
2551 if (inComposition)
2552 return;
2553 var data = text.value;
2554 sendText(data);
2555 resetValue();
2556 };
2557
2558 var handleClipboardData = function(e, data, forceIEMime) {
2559 var clipboardData = e.clipboardData || window.clipboardData;
2560 if (!clipboardData || BROKEN_SETDATA)
2561 return;
2562 var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain";
2563 try {
2564 if (data) {
2565 return clipboardData.setData(mime, data) !== false;
2566 } else {
2567 return clipboardData.getData(mime);
2568 }
2569 } catch(e) {
2570 if (!forceIEMime)
2571 return handleClipboardData(e, data, true);
2572 }
2573 };
2574
2575 var doCopy = function(e, isCut) {
2576 var data = host.getCopyText();
2577 if (!data)
2578 return event.preventDefault(e);
2579
2580 if (handleClipboardData(e, data)) {
2581 isCut ? host.onCut() : host.onCopy();
2582 event.preventDefault(e);
2583 } else {
2584 copied = true;
2585 text.value = data;
2586 text.select();
2587 setTimeout(function(){
2588 copied = false;
2589 resetValue();
2590 resetSelection();
2591 isCut ? host.onCut() : host.onCopy();
2592 });
2593 }
2594 };
2595
2596 var onCut = function(e) {
2597 doCopy(e, true);
2598 };
2599
2600 var onCopy = function(e) {
2601 doCopy(e, false);
2602 };
2603
2604 var onPaste = function(e) {
2605 var data = handleClipboardData(e);
2606 if (typeof data == "string") {
2607 if (data)
2608 host.onPaste(data, e);
2609 if (useragent.isIE)
2610 setTimeout(resetSelection);
2611 event.preventDefault(e);
2612 }
2613 else {
2614 text.value = "";
2615 pasted = true;
2616 }
2617 };
2618
2619 event.addCommandKeyListener(text, host.onCommandKey.bind(host));
2620
2621 event.addListener(text, "select", onSelect);
2622
2623 event.addListener(text, "input", onInput);
2624
2625 event.addListener(text, "cut", onCut);
2626 event.addListener(text, "copy", onCopy);
2627 event.addListener(text, "paste", onPaste);
2628 if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) {
2629 event.addListener(parentNode, "keydown", function(e) {
2630 if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
2631 return;
2632
2633 switch (e.keyCode) {
2634 case 67:
2635 onCopy(e);
2636 break;
2637 case 86:
2638 onPaste(e);
2639 break;
2640 case 88:
2641 onCut(e);
2642 break;
2643 }
2644 });
2645 }
2646 var onCompositionStart = function(e) {
2647 if (inComposition || !host.onCompositionStart || host.$readOnly)
2648 return;
2649 inComposition = {};
2650 inComposition.canUndo = host.session.$undoManager;
2651 host.onCompositionStart();
2652 setTimeout(onCompositionUpdate, 0);
2653 host.on("mousedown", onCompositionEnd);
2654 if (inComposition.canUndo && !host.selection.isEmpty()) {
2655 host.insert("");
2656 host.session.markUndoGroup();
2657 host.selection.clearSelection();
2658 }
2659 host.session.markUndoGroup();
2660 };
2661
2662 var onCompositionUpdate = function() {
2663 if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
2664 return;
2665 var val = text.value.replace(/\u2028/g, "");
2666 if (inComposition.lastValue === val) return;
2667
2668 host.onCompositionUpdate(val);
2669 if (inComposition.lastValue)
2670 host.undo();
2671 if (inComposition.canUndo)
2672 inComposition.lastValue = val;
2673 if (inComposition.lastValue) {
2674 var r = host.selection.getRange();
2675 host.insert(inComposition.lastValue);
2676 host.session.markUndoGroup();
2677 inComposition.range = host.selection.getRange();
2678 host.selection.setRange(r);
2679 host.selection.clearSelection();
2680 }
2681 };
2682
2683 var onCompositionEnd = function(e) {
2684 if (!host.onCompositionEnd || host.$readOnly) return;
2685 var c = inComposition;
2686 inComposition = false;
2687 var timer = setTimeout(function() {
2688 timer = null;
2689 var str = text.value.replace(/\u2028/g, "");
2690 if (inComposition)
2691 return;
2692 else if (str == c.lastValue)
2693 resetValue();
2694 else if (!c.lastValue && str) {
2695 resetValue();
2696 sendText(str);
2697 }
2698 });
2699 inputHandler = function compositionInputHandler(str) {
2700 if (timer)
2701 clearTimeout(timer);
2702 str = str.replace(/\u2028/g, "");
2703 if (str == c.lastValue)
2704 return "";
2705 if (c.lastValue && timer)
2706 host.undo();
2707 return str;
2708 };
2709 host.onCompositionEnd();
2710 host.removeListener("mousedown", onCompositionEnd);
2711 if (e.type == "compositionend" && c.range) {
2712 host.selection.setRange(c.range);
2713 }
2714 var needsOnInput =
2715 (!!useragent.isChrome && useragent.isChrome >= 53) ||
2716 (!!useragent.isWebKit && useragent.isWebKit >= 603);
2717
2718 if (needsOnInput) {
2719 onInput();
2720 }
2721 };
2722
2723
2724
2725 var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
2726
2727 event.addListener(text, "compositionstart", onCompositionStart);
2728 if (useragent.isGecko) {
2729 event.addListener(text, "text", function(){syncComposition.schedule();});
2730 } else {
2731 event.addListener(text, "keyup", function(){syncComposition.schedule();});
2732 event.addListener(text, "keydown", function(){syncComposition.schedule();});
2733 }
2734 event.addListener(text, "compositionend", onCompositionEnd);
2735
2736 this.getElement = function() {
2737 return text;
2738 };
2739
2740 this.setReadOnly = function(readOnly) {
2741 text.readOnly = readOnly;
2742 };
2743
2744 this.onContextMenu = function(e) {
2745 afterContextMenu = true;
2746 resetSelection(host.selection.isEmpty());
2747 host._emit("nativecontextmenu", {target: host, domEvent: e});
2748 this.moveToMouse(e, true);
2749 };
2750
2751 this.moveToMouse = function(e, bringToFront) {
2752 if (!tempStyle)
2753 tempStyle = text.style.cssText;
2754 text.style.cssText = (bringToFront ? "z-index:100000;" : "")
2755 + "height:" + text.style.height + ";"
2756 + (useragent.isIE ? "opacity:0.1;" : "");
2757
2758 var rect = host.container.getBoundingClientRect();
2759 var style = dom.computedStyle(host.container);
2760 var top = rect.top + (parseInt(style.borderTopWidth) || 0);
2761 var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
2762 var maxTop = rect.bottom - top - text.clientHeight -2;
2763 var move = function(e) {
2764 text.style.left = e.clientX - left - 2 + "px";
2765 text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
2766 };
2767 move(e);
2768
2769 if (e.type != "mousedown")
2770 return;
2771
2772 if (host.renderer.$keepTextAreaAtCursor)
2773 host.renderer.$keepTextAreaAtCursor = null;
2774
2775 clearTimeout(closeTimeout);
2776 if (useragent.isWin)
2777 event.capture(host.container, move, onContextMenuClose);
2778 };
2779
2780 this.onContextMenuClose = onContextMenuClose;
2781 var closeTimeout;
2782 function onContextMenuClose() {
2783 clearTimeout(closeTimeout);
2784 closeTimeout = setTimeout(function () {
2785 if (tempStyle) {
2786 text.style.cssText = tempStyle;
2787 tempStyle = '';
2788 }
2789 if (host.renderer.$keepTextAreaAtCursor == null) {
2790 host.renderer.$keepTextAreaAtCursor = true;
2791 host.renderer.$moveTextAreaToCursor();
2792 }
2793 }, 0);
2794 }
2795
2796 var onContextMenu = function(e) {
2797 host.textInput.onContextMenu(e);
2798 onContextMenuClose();
2799 };
2800 event.addListener(text, "mouseup", onContextMenu);
2801 event.addListener(text, "mousedown", function(e) {
2802 e.preventDefault();
2803 onContextMenuClose();
2804 });
2805 event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
2806 event.addListener(text, "contextmenu", onContextMenu);
2807 };
2808
2809 exports.TextInput = TextInput;
2810 });
2811
2812 define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
2813 "use strict";
2814
2815 var dom = require("../lib/dom");
2816 var event = require("../lib/event");
2817 var useragent = require("../lib/useragent");
2818
2819 var DRAG_OFFSET = 0; // pixels
2820 var SCROLL_COOLDOWN_T = 250; // milliseconds
2821
2822 function DefaultHandlers(mouseHandler) {
2823 mouseHandler.$clickSelection = null;
2824
2825 var editor = mouseHandler.editor;
2826 editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
2827 editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
2828 editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
2829 editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
2830 editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
2831 editor.setDefaultHandler("touchmove", this.onTouchMove.bind(mouseHandler));
2832
2833 var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd",
2834 "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"];
2835
2836 exports.forEach(function(x) {
2837 mouseHandler[x] = this[x];
2838 }, this);
2839
2840 mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
2841 mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
2842 }
2843
2844 (function() {
2845
2846 this.onMouseDown = function(ev) {
2847 var inSelection = ev.inSelection();
2848 var pos = ev.getDocumentPosition();
2849 this.mousedownEvent = ev;
2850 var editor = this.editor;
2851
2852 var button = ev.getButton();
2853 if (button !== 0) {
2854 var selectionRange = editor.getSelectionRange();
2855 var selectionEmpty = selectionRange.isEmpty();
2856 editor.$blockScrolling++;
2857 if (selectionEmpty || button == 1)
2858 editor.selection.moveToPosition(pos);
2859 editor.$blockScrolling--;
2860 if (button == 2) {
2861 editor.textInput.onContextMenu(ev.domEvent);
2862 if (!useragent.isMozilla)
2863 ev.preventDefault();
2864 }
2865 return;
2866 }
2867
2868 this.mousedownEvent.time = Date.now();
2869 if (inSelection && !editor.isFocused()) {
2870 editor.focus();
2871 if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
2872 this.setState("focusWait");
2873 this.captureMouse(ev);
2874 return;
2875 }
2876 }
2877
2878 this.captureMouse(ev);
2879 this.startSelect(pos, ev.domEvent._clicks > 1);
2880 return ev.preventDefault();
2881 };
2882
2883 this.startSelect = function(pos, waitForClickSelection) {
2884 pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
2885 var editor = this.editor;
2886 editor.$blockScrolling++;
2887 if (this.mousedownEvent.getShiftKey())
2888 editor.selection.selectToPosition(pos);
2889 else if (!waitForClickSelection)
2890 editor.selection.moveToPosition(pos);
2891 if (!waitForClickSelection)
2892 this.select();
2893 if (editor.renderer.scroller.setCapture) {
2894 editor.renderer.scroller.setCapture();
2895 }
2896 editor.setStyle("ace_selecting");
2897 this.setState("select");
2898 editor.$blockScrolling--;
2899 };
2900
2901 this.select = function() {
2902 var anchor, editor = this.editor;
2903 var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
2904 editor.$blockScrolling++;
2905 if (this.$clickSelection) {
2906 var cmp = this.$clickSelection.comparePoint(cursor);
2907
2908 if (cmp == -1) {
2909 anchor = this.$clickSelection.end;
2910 } else if (cmp == 1) {
2911 anchor = this.$clickSelection.start;
2912 } else {
2913 var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
2914 cursor = orientedRange.cursor;
2915 anchor = orientedRange.anchor;
2916 }
2917 editor.selection.setSelectionAnchor(anchor.row, anchor.column);
2918 }
2919 editor.selection.selectToPosition(cursor);
2920 editor.$blockScrolling--;
2921 editor.renderer.scrollCursorIntoView();
2922 };
2923
2924 this.extendSelectionBy = function(unitName) {
2925 var anchor, editor = this.editor;
2926 var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
2927 var range = editor.selection[unitName](cursor.row, cursor.column);
2928 editor.$blockScrolling++;
2929 if (this.$clickSelection) {
2930 var cmpStart = this.$clickSelection.comparePoint(range.start);
2931 var cmpEnd = this.$clickSelection.comparePoint(range.end);
2932
2933 if (cmpStart == -1 && cmpEnd <= 0) {
2934 anchor = this.$clickSelection.end;
2935 if (range.end.row != cursor.row || range.end.column != cursor.column)
2936 cursor = range.start;
2937 } else if (cmpEnd == 1 && cmpStart >= 0) {
2938 anchor = this.$clickSelection.start;
2939 if (range.start.row != cursor.row || range.start.column != cursor.column)
2940 cursor = range.end;
2941 } else if (cmpStart == -1 && cmpEnd == 1) {
2942 cursor = range.end;
2943 anchor = range.start;
2944 } else {
2945 var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
2946 cursor = orientedRange.cursor;
2947 anchor = orientedRange.anchor;
2948 }
2949 editor.selection.setSelectionAnchor(anchor.row, anchor.column);
2950 }
2951 editor.selection.selectToPosition(cursor);
2952 editor.$blockScrolling--;
2953 editor.renderer.scrollCursorIntoView();
2954 };
2955
2956 this.selectEnd =
2957 this.selectAllEnd =
2958 this.selectByWordsEnd =
2959 this.selectByLinesEnd = function() {
2960 this.$clickSelection = null;
2961 this.editor.unsetStyle("ace_selecting");
2962 if (this.editor.renderer.scroller.releaseCapture) {
2963 this.editor.renderer.scroller.releaseCapture();
2964 }
2965 };
2966
2967 this.focusWait = function() {
2968 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
2969 var time = Date.now();
2970
2971 if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
2972 this.startSelect(this.mousedownEvent.getDocumentPosition());
2973 };
2974
2975 this.onDoubleClick = function(ev) {
2976 var pos = ev.getDocumentPosition();
2977 var editor = this.editor;
2978 var session = editor.session;
2979
2980 var range = session.getBracketRange(pos);
2981 if (range) {
2982 if (range.isEmpty()) {
2983 range.start.column--;
2984 range.end.column++;
2985 }
2986 this.setState("select");
2987 } else {
2988 range = editor.selection.getWordRange(pos.row, pos.column);
2989 this.setState("selectByWords");
2990 }
2991 this.$clickSelection = range;
2992 this.select();
2993 };
2994
2995 this.onTripleClick = function(ev) {
2996 var pos = ev.getDocumentPosition();
2997 var editor = this.editor;
2998
2999 this.setState("selectByLines");
3000 var range = editor.getSelectionRange();
3001 if (range.isMultiLine() && range.contains(pos.row, pos.column)) {
3002 this.$clickSelection = editor.selection.getLineRange(range.start.row);
3003 this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;
3004 } else {
3005 this.$clickSelection = editor.selection.getLineRange(pos.row);
3006 }
3007 this.select();
3008 };
3009
3010 this.onQuadClick = function(ev) {
3011 var editor = this.editor;
3012
3013 editor.selectAll();
3014 this.$clickSelection = editor.getSelectionRange();
3015 this.setState("selectAll");
3016 };
3017
3018 this.onMouseWheel = function(ev) {
3019 if (ev.getAccelKey())
3020 return;
3021 if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {
3022 ev.wheelX = ev.wheelY;
3023 ev.wheelY = 0;
3024 }
3025
3026 var editor = this.editor;
3027
3028 if (!this.$lastScroll)
3029 this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 };
3030
3031 var prevScroll = this.$lastScroll;
3032 var t = ev.domEvent.timeStamp;
3033 var dt = t - prevScroll.t;
3034 var vx = ev.wheelX / dt;
3035 var vy = ev.wheelY / dt;
3036 if (dt < SCROLL_COOLDOWN_T) {
3037 vx = (vx + prevScroll.vx) / 2;
3038 vy = (vy + prevScroll.vy) / 2;
3039 }
3040
3041 var direction = Math.abs(vx / vy);
3042
3043 var canScroll = false;
3044 if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0))
3045 canScroll = true;
3046 if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed))
3047 canScroll = true;
3048
3049 if (canScroll) {
3050 prevScroll.allowed = t;
3051 } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) {
3052 var isSlower = Math.abs(vx) <= 1.1 * Math.abs(prevScroll.vx)
3053 && Math.abs(vy) <= 1.1 * Math.abs(prevScroll.vy);
3054 if (isSlower) {
3055 canScroll = true;
3056 prevScroll.allowed = t;
3057 }
3058 else {
3059 prevScroll.allowed = 0;
3060 }
3061 }
3062
3063 prevScroll.t = t;
3064 prevScroll.vx = vx;
3065 prevScroll.vy = vy;
3066
3067 if (canScroll) {
3068 editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
3069 return ev.stop();
3070 }
3071 };
3072
3073 this.onTouchMove = function(ev) {
3074 this.editor._emit("mousewheel", ev);
3075 };
3076
3077 }).call(DefaultHandlers.prototype);
3078
3079 exports.DefaultHandlers = DefaultHandlers;
3080
3081 function calcDistance(ax, ay, bx, by) {
3082 return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
3083 }
3084
3085 function calcRangeOrientation(range, cursor) {
3086 if (range.start.row == range.end.row)
3087 var cmp = 2 * cursor.column - range.start.column - range.end.column;
3088 else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)
3089 var cmp = cursor.column - 4;
3090 else
3091 var cmp = 2 * cursor.row - range.start.row - range.end.row;
3092
3093 if (cmp < 0)
3094 return {cursor: range.start, anchor: range.end};
3095 else
3096 return {cursor: range.end, anchor: range.start};
3097 }
3098
3099 });
3100
3101 define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(require, exports, module) {
3102 "use strict";
3103
3104 var oop = require("./lib/oop");
3105 var dom = require("./lib/dom");
3106 function Tooltip (parentNode) {
3107 this.isOpen = false;
3108 this.$element = null;
3109 this.$parentNode = parentNode;
3110 }
3111
3112 (function() {
3113 this.$init = function() {
3114 this.$element = dom.createElement("div");
3115 this.$element.className = "ace_tooltip";
3116 this.$element.style.display = "none";
3117 this.$parentNode.appendChild(this.$element);
3118 return this.$element;
3119 };
3120 this.getElement = function() {
3121 return this.$element || this.$init();
3122 };
3123 this.setText = function(text) {
3124 dom.setInnerText(this.getElement(), text);
3125 };
3126 this.setHtml = function(html) {
3127 this.getElement().innerHTML = html;
3128 };
3129 this.setPosition = function(x, y) {
3130 this.getElement().style.left = x + "px";
3131 this.getElement().style.top = y + "px";
3132 };
3133 this.setClassName = function(className) {
3134 dom.addCssClass(this.getElement(), className);
3135 };
3136 this.show = function(text, x, y) {
3137 if (text != null)
3138 this.setText(text);
3139 if (x != null && y != null)
3140 this.setPosition(x, y);
3141 if (!this.isOpen) {
3142 this.getElement().style.display = "block";
3143 this.isOpen = true;
3144 }
3145 };
3146
3147 this.hide = function() {
3148 if (this.isOpen) {
3149 this.getElement().style.display = "none";
3150 this.isOpen = false;
3151 }
3152 };
3153 this.getHeight = function() {
3154 return this.getElement().offsetHeight;
3155 };
3156 this.getWidth = function() {
3157 return this.getElement().offsetWidth;
3158 };
3159
3160 this.destroy = function() {
3161 this.isOpen = false;
3162 if (this.$element && this.$element.parentNode) {
3163 this.$element.parentNode.removeChild(this.$element);
3164 }
3165 };
3166
3167 }).call(Tooltip.prototype);
3168
3169 exports.Tooltip = Tooltip;
3170 });
3171
3172 define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(require, exports, module) {
3173 "use strict";
3174 var dom = require("../lib/dom");
3175 var oop = require("../lib/oop");
3176 var event = require("../lib/event");
3177 var Tooltip = require("../tooltip").Tooltip;
3178
3179 function GutterHandler(mouseHandler) {
3180 var editor = mouseHandler.editor;
3181 var gutter = editor.renderer.$gutterLayer;
3182 var tooltip = new GutterTooltip(editor.container);
3183
3184 mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
3185 if (!editor.isFocused() || e.getButton() != 0)
3186 return;
3187 var gutterRegion = gutter.getRegion(e);
3188
3189 if (gutterRegion == "foldWidgets")
3190 return;
3191
3192 var row = e.getDocumentPosition().row;
3193 var selection = editor.session.selection;
3194
3195 if (e.getShiftKey())
3196 selection.selectTo(row, 0);
3197 else {
3198 if (e.domEvent.detail == 2) {
3199 editor.selectAll();
3200 return e.preventDefault();
3201 }
3202 mouseHandler.$clickSelection = editor.selection.getLineRange(row);
3203 }
3204 mouseHandler.setState("selectByLines");
3205 mouseHandler.captureMouse(e);
3206 return e.preventDefault();
3207 });
3208
3209
3210 var tooltipTimeout, mouseEvent, tooltipAnnotation;
3211
3212 function showTooltip() {
3213 var row = mouseEvent.getDocumentPosition().row;
3214 var annotation = gutter.$annotations[row];
3215 if (!annotation)
3216 return hideTooltip();
3217
3218 var maxRow = editor.session.getLength();
3219 if (row == maxRow) {
3220 var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
3221 var pos = mouseEvent.$pos;
3222 if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
3223 return hideTooltip();
3224 }
3225
3226 if (tooltipAnnotation == annotation)
3227 return;
3228 tooltipAnnotation = annotation.text.join("<br/>");
3229
3230 tooltip.setHtml(tooltipAnnotation);
3231 tooltip.show();
3232 editor._signal("showGutterTooltip", tooltip);
3233 editor.on("mousewheel", hideTooltip);
3234
3235 if (mouseHandler.$tooltipFollowsMouse) {
3236 moveTooltip(mouseEvent);
3237 } else {
3238 var gutterElement = mouseEvent.domEvent.target;
3239 var rect = gutterElement.getBoundingClientRect();
3240 var style = tooltip.getElement().style;
3241 style.left = rect.right + "px";
3242 style.top = rect.bottom + "px";
3243 }
3244 }
3245
3246 function hideTooltip() {
3247 if (tooltipTimeout)
3248 tooltipTimeout = clearTimeout(tooltipTimeout);
3249 if (tooltipAnnotation) {
3250 tooltip.hide();
3251 tooltipAnnotation = null;
3252 editor._signal("hideGutterTooltip", tooltip);
3253 editor.removeEventListener("mousewheel", hideTooltip);
3254 }
3255 }
3256
3257 function moveTooltip(e) {
3258 tooltip.setPosition(e.x, e.y);
3259 }
3260
3261 mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
3262 var target = e.domEvent.target || e.domEvent.srcElement;
3263 if (dom.hasCssClass(target, "ace_fold-widget"))
3264 return hideTooltip();
3265
3266 if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)
3267 moveTooltip(e);
3268
3269 mouseEvent = e;
3270 if (tooltipTimeout)
3271 return;
3272 tooltipTimeout = setTimeout(function() {
3273 tooltipTimeout = null;
3274 if (mouseEvent && !mouseHandler.isMousePressed)
3275 showTooltip();
3276 else
3277 hideTooltip();
3278 }, 50);
3279 });
3280
3281 event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
3282 mouseEvent = null;
3283 if (!tooltipAnnotation || tooltipTimeout)
3284 return;
3285
3286 tooltipTimeout = setTimeout(function() {
3287 tooltipTimeout = null;
3288 hideTooltip();
3289 }, 50);
3290 });
3291
3292 editor.on("changeSession", hideTooltip);
3293 }
3294
3295 function GutterTooltip(parentNode) {
3296 Tooltip.call(this, parentNode);
3297 }
3298
3299 oop.inherits(GutterTooltip, Tooltip);
3300
3301 (function(){
3302 this.setPosition = function(x, y) {
3303 var windowWidth = window.innerWidth || document.documentElement.clientWidth;
3304 var windowHeight = window.innerHeight || document.documentElement.clientHeight;
3305 var width = this.getWidth();
3306 var height = this.getHeight();
3307 x += 15;
3308 y += 15;
3309 if (x + width > windowWidth) {
3310 x -= (x + width) - windowWidth;
3311 }
3312 if (y + height > windowHeight) {
3313 y -= 20 + height;
3314 }
3315 Tooltip.prototype.setPosition.call(this, x, y);
3316 };
3317
3318 }).call(GutterTooltip.prototype);
3319
3320
3321
3322 exports.GutterHandler = GutterHandler;
3323
3324 });
3325
3326 define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
3327 "use strict";
3328
3329 var event = require("../lib/event");
3330 var useragent = require("../lib/useragent");
3331 var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
3332 this.domEvent = domEvent;
3333 this.editor = editor;
3334
3335 this.x = this.clientX = domEvent.clientX;
3336 this.y = this.clientY = domEvent.clientY;
3337
3338 this.$pos = null;
3339 this.$inSelection = null;
3340
3341 this.propagationStopped = false;
3342 this.defaultPrevented = false;
3343 };
3344
3345 (function() {
3346
3347 this.stopPropagation = function() {
3348 event.stopPropagation(this.domEvent);
3349 this.propagationStopped = true;
3350 };
3351
3352 this.preventDefault = function() {
3353 event.preventDefault(this.domEvent);
3354 this.defaultPrevented = true;
3355 };
3356
3357 this.stop = function() {
3358 this.stopPropagation();
3359 this.preventDefault();
3360 };
3361 this.getDocumentPosition = function() {
3362 if (this.$pos)
3363 return this.$pos;
3364
3365 this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
3366 return this.$pos;
3367 };
3368 this.inSelection = function() {
3369 if (this.$inSelection !== null)
3370 return this.$inSelection;
3371
3372 var editor = this.editor;
3373
3374
3375 var selectionRange = editor.getSelectionRange();
3376 if (selectionRange.isEmpty())
3377 this.$inSelection = false;
3378 else {
3379 var pos = this.getDocumentPosition();
3380 this.$inSelection = selectionRange.contains(pos.row, pos.column);
3381 }
3382
3383 return this.$inSelection;
3384 };
3385 this.getButton = function() {
3386 return event.getButton(this.domEvent);
3387 };
3388 this.getShiftKey = function() {
3389 return this.domEvent.shiftKey;
3390 };
3391
3392 this.getAccelKey = useragent.isMac
3393 ? function() { return this.domEvent.metaKey; }
3394 : function() { return this.domEvent.ctrlKey; };
3395
3396 }).call(MouseEvent.prototype);
3397
3398 });
3399
3400 define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
3401 "use strict";
3402
3403 var dom = require("../lib/dom");
3404 var event = require("../lib/event");
3405 var useragent = require("../lib/useragent");
3406
3407 var AUTOSCROLL_DELAY = 200;
3408 var SCROLL_CURSOR_DELAY = 200;
3409 var SCROLL_CURSOR_HYSTERESIS = 5;
3410
3411 function DragdropHandler(mouseHandler) {
3412
3413 var editor = mouseHandler.editor;
3414
3415 var blankImage = dom.createElement("img");
3416 blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
3417 if (useragent.isOpera)
3418 blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;";
3419
3420 var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"];
3421
3422 exports.forEach(function(x) {
3423 mouseHandler[x] = this[x];
3424 }, this);
3425 editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler));
3426
3427
3428 var mouseTarget = editor.container;
3429 var dragSelectionMarker, x, y;
3430 var timerId, range;
3431 var dragCursor, counter = 0;
3432 var dragOperation;
3433 var isInternal;
3434 var autoScrollStartTime;
3435 var cursorMovedTime;
3436 var cursorPointOnCaretMoved;
3437
3438 this.onDragStart = function(e) {
3439 if (this.cancelDrag || !mouseTarget.draggable) {
3440 var self = this;
3441 setTimeout(function(){
3442 self.startSelect();
3443 self.captureMouse(e);
3444 }, 0);
3445 return e.preventDefault();
3446 }
3447 range = editor.getSelectionRange();
3448
3449 var dataTransfer = e.dataTransfer;
3450 dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove";
3451 if (useragent.isOpera) {
3452 editor.container.appendChild(blankImage);
3453 blankImage.scrollTop = 0;
3454 }
3455 dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0);
3456 if (useragent.isOpera) {
3457 editor.container.removeChild(blankImage);
3458 }
3459 dataTransfer.clearData();
3460 dataTransfer.setData("Text", editor.session.getTextRange());
3461
3462 isInternal = true;
3463 this.setState("drag");
3464 };
3465
3466 this.onDragEnd = function(e) {
3467 mouseTarget.draggable = false;
3468 isInternal = false;
3469 this.setState(null);
3470 if (!editor.getReadOnly()) {
3471 var dropEffect = e.dataTransfer.dropEffect;
3472 if (!dragOperation && dropEffect == "move")
3473 editor.session.remove(editor.getSelectionRange());
3474 editor.renderer.$cursorLayer.setBlinking(true);
3475 }
3476 this.editor.unsetStyle("ace_dragging");
3477 this.editor.renderer.setCursorStyle("");
3478 };
3479
3480 this.onDragEnter = function(e) {
3481 if (editor.getReadOnly() || !canAccept(e.dataTransfer))
3482 return;
3483 x = e.clientX;
3484 y = e.clientY;
3485 if (!dragSelectionMarker)
3486 addDragMarker();
3487 counter++;
3488 e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
3489 return event.preventDefault(e);
3490 };
3491
3492 this.onDragOver = function(e) {
3493 if (editor.getReadOnly() || !canAccept(e.dataTransfer))
3494 return;
3495 x = e.clientX;
3496 y = e.clientY;
3497 if (!dragSelectionMarker) {
3498 addDragMarker();
3499 counter++;
3500 }
3501 if (onMouseMoveTimer !== null)
3502 onMouseMoveTimer = null;
3503
3504 e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
3505 return event.preventDefault(e);
3506 };
3507
3508 this.onDragLeave = function(e) {
3509 counter--;
3510 if (counter <= 0 && dragSelectionMarker) {
3511 clearDragMarker();
3512 dragOperation = null;
3513 return event.preventDefault(e);
3514 }
3515 };
3516
3517 this.onDrop = function(e) {
3518 if (!dragCursor)
3519 return;
3520 var dataTransfer = e.dataTransfer;
3521 if (isInternal) {
3522 switch (dragOperation) {
3523 case "move":
3524 if (range.contains(dragCursor.row, dragCursor.column)) {
3525 range = {
3526 start: dragCursor,
3527 end: dragCursor
3528 };
3529 } else {
3530 range = editor.moveText(range, dragCursor);
3531 }
3532 break;
3533 case "copy":
3534 range = editor.moveText(range, dragCursor, true);
3535 break;
3536 }
3537 } else {
3538 var dropData = dataTransfer.getData('Text');
3539 range = {
3540 start: dragCursor,
3541 end: editor.session.insert(dragCursor, dropData)
3542 };
3543 editor.focus();
3544 dragOperation = null;
3545 }
3546 clearDragMarker();
3547 return event.preventDefault(e);
3548 };
3549
3550 event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler));
3551 event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler));
3552 event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler));
3553 event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler));
3554 event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler));
3555 event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler));
3556
3557 function scrollCursorIntoView(cursor, prevCursor) {
3558 var now = Date.now();
3559 var vMovement = !prevCursor || cursor.row != prevCursor.row;
3560 var hMovement = !prevCursor || cursor.column != prevCursor.column;
3561 if (!cursorMovedTime || vMovement || hMovement) {
3562 editor.$blockScrolling += 1;
3563 editor.moveCursorToPosition(cursor);
3564 editor.$blockScrolling -= 1;
3565 cursorMovedTime = now;
3566 cursorPointOnCaretMoved = {x: x, y: y};
3567 } else {
3568 var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y);
3569 if (distance > SCROLL_CURSOR_HYSTERESIS) {
3570 cursorMovedTime = null;
3571 } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) {
3572 editor.renderer.scrollCursorIntoView();
3573 cursorMovedTime = null;
3574 }
3575 }
3576 }
3577
3578 function autoScroll(cursor, prevCursor) {
3579 var now = Date.now();
3580 var lineHeight = editor.renderer.layerConfig.lineHeight;
3581 var characterWidth = editor.renderer.layerConfig.characterWidth;
3582 var editorRect = editor.renderer.scroller.getBoundingClientRect();
3583 var offsets = {
3584 x: {
3585 left: x - editorRect.left,
3586 right: editorRect.right - x
3587 },
3588 y: {
3589 top: y - editorRect.top,
3590 bottom: editorRect.bottom - y
3591 }
3592 };
3593 var nearestXOffset = Math.min(offsets.x.left, offsets.x.right);
3594 var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom);
3595 var scrollCursor = {row: cursor.row, column: cursor.column};
3596 if (nearestXOffset / characterWidth <= 2) {
3597 scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2);
3598 }
3599 if (nearestYOffset / lineHeight <= 1) {
3600 scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1);
3601 }
3602 var vScroll = cursor.row != scrollCursor.row;
3603 var hScroll = cursor.column != scrollCursor.column;
3604 var vMovement = !prevCursor || cursor.row != prevCursor.row;
3605 if (vScroll || (hScroll && !vMovement)) {
3606 if (!autoScrollStartTime)
3607 autoScrollStartTime = now;
3608 else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY)
3609 editor.renderer.scrollCursorIntoView(scrollCursor);
3610 } else {
3611 autoScrollStartTime = null;
3612 }
3613 }
3614
3615 function onDragInterval() {
3616 var prevCursor = dragCursor;
3617 dragCursor = editor.renderer.screenToTextCoordinates(x, y);
3618 scrollCursorIntoView(dragCursor, prevCursor);
3619 autoScroll(dragCursor, prevCursor);
3620 }
3621
3622 function addDragMarker() {
3623 range = editor.selection.toOrientedRange();
3624 dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
3625 editor.clearSelection();
3626 if (editor.isFocused())
3627 editor.renderer.$cursorLayer.setBlinking(false);
3628 clearInterval(timerId);
3629 onDragInterval();
3630 timerId = setInterval(onDragInterval, 20);
3631 counter = 0;
3632 event.addListener(document, "mousemove", onMouseMove);
3633 }
3634
3635 function clearDragMarker() {
3636 clearInterval(timerId);
3637 editor.session.removeMarker(dragSelectionMarker);
3638 dragSelectionMarker = null;
3639 editor.$blockScrolling += 1;
3640 editor.selection.fromOrientedRange(range);
3641 editor.$blockScrolling -= 1;
3642 if (editor.isFocused() && !isInternal)
3643 editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly());
3644 range = null;
3645 dragCursor = null;
3646 counter = 0;
3647 autoScrollStartTime = null;
3648 cursorMovedTime = null;
3649 event.removeListener(document, "mousemove", onMouseMove);
3650 }
3651 var onMouseMoveTimer = null;
3652 function onMouseMove() {
3653 if (onMouseMoveTimer == null) {
3654 onMouseMoveTimer = setTimeout(function() {
3655 if (onMouseMoveTimer != null && dragSelectionMarker)
3656 clearDragMarker();
3657 }, 20);
3658 }
3659 }
3660
3661 function canAccept(dataTransfer) {
3662 var types = dataTransfer.types;
3663 return !types || Array.prototype.some.call(types, function(type) {
3664 return type == 'text/plain' || type == 'Text';
3665 });
3666 }
3667
3668 function getDropEffect(e) {
3669 var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];
3670 var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];
3671
3672 var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey;
3673 var effectAllowed = "uninitialized";
3674 try {
3675 effectAllowed = e.dataTransfer.effectAllowed.toLowerCase();
3676 } catch (e) {}
3677 var dropEffect = "none";
3678
3679 if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0)
3680 dropEffect = "copy";
3681 else if (moveAllowed.indexOf(effectAllowed) >= 0)
3682 dropEffect = "move";
3683 else if (copyAllowed.indexOf(effectAllowed) >= 0)
3684 dropEffect = "copy";
3685
3686 return dropEffect;
3687 }
3688 }
3689
3690 (function() {
3691
3692 this.dragWait = function() {
3693 var interval = Date.now() - this.mousedownEvent.time;
3694 if (interval > this.editor.getDragDelay())
3695 this.startDrag();
3696 };
3697
3698 this.dragWaitEnd = function() {
3699 var target = this.editor.container;
3700 target.draggable = false;
3701 this.startSelect(this.mousedownEvent.getDocumentPosition());
3702 this.selectEnd();
3703 };
3704
3705 this.dragReadyEnd = function(e) {
3706 this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly());
3707 this.editor.unsetStyle("ace_dragging");
3708 this.editor.renderer.setCursorStyle("");
3709 this.dragWaitEnd();
3710 };
3711
3712 this.startDrag = function(){
3713 this.cancelDrag = false;
3714 var editor = this.editor;
3715 var target = editor.container;
3716 target.draggable = true;
3717 editor.renderer.$cursorLayer.setBlinking(false);
3718 editor.setStyle("ace_dragging");
3719 var cursorStyle = useragent.isWin ? "default" : "move";
3720 editor.renderer.setCursorStyle(cursorStyle);
3721 this.setState("dragReady");
3722 };
3723
3724 this.onMouseDrag = function(e) {
3725 var target = this.editor.container;
3726 if (useragent.isIE && this.state == "dragReady") {
3727 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3728 if (distance > 3)
3729 target.dragDrop();
3730 }
3731 if (this.state === "dragWait") {
3732 var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3733 if (distance > 0) {
3734 target.draggable = false;
3735 this.startSelect(this.mousedownEvent.getDocumentPosition());
3736 }
3737 }
3738 };
3739
3740 this.onMouseDown = function(e) {
3741 if (!this.$dragEnabled)
3742 return;
3743 this.mousedownEvent = e;
3744 var editor = this.editor;
3745
3746 var inSelection = e.inSelection();
3747 var button = e.getButton();
3748 var clickCount = e.domEvent.detail || 1;
3749 if (clickCount === 1 && button === 0 && inSelection) {
3750 if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey()))
3751 return;
3752 this.mousedownEvent.time = Date.now();
3753 var eventTarget = e.domEvent.target || e.domEvent.srcElement;
3754 if ("unselectable" in eventTarget)
3755 eventTarget.unselectable = "on";
3756 if (editor.getDragDelay()) {
3757 if (useragent.isWebKit) {
3758 this.cancelDrag = true;
3759 var mouseTarget = editor.container;
3760 mouseTarget.draggable = true;
3761 }
3762 this.setState("dragWait");
3763 } else {
3764 this.startDrag();
3765 }
3766 this.captureMouse(e, this.onMouseDrag.bind(this));
3767 e.defaultPrevented = true;
3768 }
3769 };
3770
3771 }).call(DragdropHandler.prototype);
3772
3773
3774 function calcDistance(ax, ay, bx, by) {
3775 return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
3776 }
3777
3778 exports.DragdropHandler = DragdropHandler;
3779
3780 });
3781
3782 define("ace/lib/net",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
3783 "use strict";
3784 var dom = require("./dom");
3785
3786 exports.get = function (url, callback) {
3787 var xhr = new XMLHttpRequest();
3788 xhr.open('GET', url, true);
3789 xhr.onreadystatechange = function () {
3790 if (xhr.readyState === 4) {
3791 callback(xhr.responseText);
3792 }
3793 };
3794 xhr.send(null);
3795 };
3796
3797 exports.loadScript = function(path, callback) {
3798 var head = dom.getDocumentHead();
3799 var s = document.createElement('script');
3800
3801 s.src = path;
3802 head.appendChild(s);
3803
3804 s.onload = s.onreadystatechange = function(_, isAbort) {
3805 if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
3806 s = s.onload = s.onreadystatechange = null;
3807 if (!isAbort)
3808 callback();
3809 }
3810 };
3811 };
3812 exports.qualifyURL = function(url) {
3813 var a = document.createElement('a');
3814 a.href = url;
3815 return a.href;
3816 };
3817
3818 });
3819
3820 define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) {
3821 "use strict";
3822
3823 var EventEmitter = {};
3824 var stopPropagation = function() { this.propagationStopped = true; };
3825 var preventDefault = function() { this.defaultPrevented = true; };
3826
3827 EventEmitter._emit =
3828 EventEmitter._dispatchEvent = function(eventName, e) {
3829 this._eventRegistry || (this._eventRegistry = {});
3830 this._defaultHandlers || (this._defaultHandlers = {});
3831
3832 var listeners = this._eventRegistry[eventName] || [];
3833 var defaultHandler = this._defaultHandlers[eventName];
3834 if (!listeners.length && !defaultHandler)
3835 return;
3836
3837 if (typeof e != "object" || !e)
3838 e = {};
3839
3840 if (!e.type)
3841 e.type = eventName;
3842 if (!e.stopPropagation)
3843 e.stopPropagation = stopPropagation;
3844 if (!e.preventDefault)
3845 e.preventDefault = preventDefault;
3846
3847 listeners = listeners.slice();
3848 for (var i=0; i<listeners.length; i++) {
3849 listeners[i](e, this);
3850 if (e.propagationStopped)
3851 break;
3852 }
3853
3854 if (defaultHandler && !e.defaultPrevented)
3855 return defaultHandler(e, this);
3856 };
3857
3858
3859 EventEmitter._signal = function(eventName, e) {
3860 var listeners = (this._eventRegistry || {})[eventName];
3861 if (!listeners)
3862 return;
3863 listeners = listeners.slice();
3864 for (var i=0; i<listeners.length; i++)
3865 listeners[i](e, this);
3866 };
3867
3868 EventEmitter.once = function(eventName, callback) {
3869 var _self = this;
3870 callback && this.addEventListener(eventName, function newCallback() {
3871 _self.removeEventListener(eventName, newCallback);
3872 callback.apply(null, arguments);
3873 });
3874 };
3875
3876
3877 EventEmitter.setDefaultHandler = function(eventName, callback) {
3878 var handlers = this._defaultHandlers;
3879 if (!handlers)
3880 handlers = this._defaultHandlers = {_disabled_: {}};
3881
3882 if (handlers[eventName]) {
3883 var old = handlers[eventName];
3884 var disabled = handlers._disabled_[eventName];
3885 if (!disabled)
3886 handlers._disabled_[eventName] = disabled = [];
3887 disabled.push(old);
3888 var i = disabled.indexOf(callback);
3889 if (i != -1)
3890 disabled.splice(i, 1);
3891 }
3892 handlers[eventName] = callback;
3893 };
3894 EventEmitter.removeDefaultHandler = function(eventName, callback) {
3895 var handlers = this._defaultHandlers;
3896 if (!handlers)
3897 return;
3898 var disabled = handlers._disabled_[eventName];
3899
3900 if (handlers[eventName] == callback) {
3901 var old = handlers[eventName];
3902 if (disabled)
3903 this.setDefaultHandler(eventName, disabled.pop());
3904 } else if (disabled) {
3905 var i = disabled.indexOf(callback);
3906 if (i != -1)
3907 disabled.splice(i, 1);
3908 }
3909 };
3910
3911 EventEmitter.on =
3912 EventEmitter.addEventListener = function(eventName, callback, capturing) {
3913 this._eventRegistry = this._eventRegistry || {};
3914
3915 var listeners = this._eventRegistry[eventName];
3916 if (!listeners)
3917 listeners = this._eventRegistry[eventName] = [];
3918
3919 if (listeners.indexOf(callback) == -1)
3920 listeners[capturing ? "unshift" : "push"](callback);
3921 return callback;
3922 };
3923
3924 EventEmitter.off =
3925 EventEmitter.removeListener =
3926 EventEmitter.removeEventListener = function(eventName, callback) {
3927 this._eventRegistry = this._eventRegistry || {};
3928
3929 var listeners = this._eventRegistry[eventName];
3930 if (!listeners)
3931 return;
3932
3933 var index = listeners.indexOf(callback);
3934 if (index !== -1)
3935 listeners.splice(index, 1);
3936 };
3937
3938 EventEmitter.removeAllListeners = function(eventName) {
3939 if (this._eventRegistry) this._eventRegistry[eventName] = [];
3940 };
3941
3942 exports.EventEmitter = EventEmitter;
3943
3944 });
3945
3946 define("ace/lib/app_config",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) {
3947 "no use strict";
3948
3949 var oop = require("./oop");
3950 var EventEmitter = require("./event_emitter").EventEmitter;
3951
3952 var optionsProvider = {
3953 setOptions: function(optList) {
3954 Object.keys(optList).forEach(function(key) {
3955 this.setOption(key, optList[key]);
3956 }, this);
3957 },
3958 getOptions: function(optionNames) {
3959 var result = {};
3960 if (!optionNames) {
3961 optionNames = Object.keys(this.$options);
3962 } else if (!Array.isArray(optionNames)) {
3963 result = optionNames;
3964 optionNames = Object.keys(result);
3965 }
3966 optionNames.forEach(function(key) {
3967 result[key] = this.getOption(key);
3968 }, this);
3969 return result;
3970 },
3971 setOption: function(name, value) {
3972 if (this["$" + name] === value)
3973 return;
3974 var opt = this.$options[name];
3975 if (!opt) {
3976 return warn('misspelled option "' + name + '"');
3977 }
3978 if (opt.forwardTo)
3979 return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
3980
3981 if (!opt.handlesSet)
3982 this["$" + name] = value;
3983 if (opt && opt.set)
3984 opt.set.call(this, value);
3985 },
3986 getOption: function(name) {
3987 var opt = this.$options[name];
3988 if (!opt) {
3989 return warn('misspelled option "' + name + '"');
3990 }
3991 if (opt.forwardTo)
3992 return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
3993 return opt && opt.get ? opt.get.call(this) : this["$" + name];
3994 }
3995 };
3996
3997 function warn(message) {
3998 if (typeof console != "undefined" && console.warn)
3999 console.warn.apply(console, arguments);
4000 }
4001
4002 function reportError(msg, data) {
4003 var e = new Error(msg);
4004 e.data = data;
4005 if (typeof console == "object" && console.error)
4006 console.error(e);
4007 setTimeout(function() { throw e; });
4008 }
4009
4010 var AppConfig = function() {
4011 this.$defaultOptions = {};
4012 };
4013
4014 (function() {
4015 oop.implement(this, EventEmitter);
4016 this.defineOptions = function(obj, path, options) {
4017 if (!obj.$options)
4018 this.$defaultOptions[path] = obj.$options = {};
4019
4020 Object.keys(options).forEach(function(key) {
4021 var opt = options[key];
4022 if (typeof opt == "string")
4023 opt = {forwardTo: opt};
4024
4025 opt.name || (opt.name = key);
4026 obj.$options[opt.name] = opt;
4027 if ("initialValue" in opt)
4028 obj["$" + opt.name] = opt.initialValue;
4029 });
4030 oop.implement(obj, optionsProvider);
4031
4032 return this;
4033 };
4034
4035 this.resetOptions = function(obj) {
4036 Object.keys(obj.$options).forEach(function(key) {
4037 var opt = obj.$options[key];
4038 if ("value" in opt)
4039 obj.setOption(key, opt.value);
4040 });
4041 };
4042
4043 this.setDefaultValue = function(path, name, value) {
4044 var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {});
4045 if (opts[name]) {
4046 if (opts.forwardTo)
4047 this.setDefaultValue(opts.forwardTo, name, value);
4048 else
4049 opts[name].value = value;
4050 }
4051 };
4052
4053 this.setDefaultValues = function(path, optionHash) {
4054 Object.keys(optionHash).forEach(function(key) {
4055 this.setDefaultValue(path, key, optionHash[key]);
4056 }, this);
4057 };
4058
4059 this.warn = warn;
4060 this.reportError = reportError;
4061
4062 }).call(AppConfig.prototype);
4063
4064 exports.AppConfig = AppConfig;
4065
4066 });
4067
4068 define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/app_config"], function(require, exports, module) {
4069 "no use strict";
4070
4071 var lang = require("./lib/lang");
4072 var oop = require("./lib/oop");
4073 var net = require("./lib/net");
4074 var AppConfig = require("./lib/app_config").AppConfig;
4075
4076 module.exports = exports = new AppConfig();
4077
4078 var global = (function() {
4079 return this || typeof window != "undefined" && window;
4080 })();
4081
4082 var options = {
4083 packaged: false,
4084 workerPath: null,
4085 modePath: null,
4086 themePath: null,
4087 basePath: "",
4088 suffix: ".js",
4089 $moduleUrls: {}
4090 };
4091
4092 exports.get = function(key) {
4093 if (!options.hasOwnProperty(key))
4094 throw new Error("Unknown config key: " + key);
4095
4096 return options[key];
4097 };
4098
4099 exports.set = function(key, value) {
4100 if (!options.hasOwnProperty(key))
4101 throw new Error("Unknown config key: " + key);
4102
4103 options[key] = value;
4104 };
4105
4106 exports.all = function() {
4107 return lang.copyObject(options);
4108 };
4109 exports.moduleUrl = function(name, component) {
4110 if (options.$moduleUrls[name])
4111 return options.$moduleUrls[name];
4112
4113 var parts = name.split("/");
4114 component = component || parts[parts.length - 2] || "";
4115 var sep = component == "snippets" ? "/" : "-";
4116 var base = parts[parts.length - 1];
4117 if (component == "worker" && sep == "-") {
4118 var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g");
4119 base = base.replace(re, "");
4120 }
4121
4122 if ((!base || base == component) && parts.length > 1)
4123 base = parts[parts.length - 2];
4124 var path = options[component + "Path"];
4125 if (path == null) {
4126 path = options.basePath;
4127 } else if (sep == "/") {
4128 component = sep = "";
4129 }
4130 if (path && path.slice(-1) != "/")
4131 path += "/";
4132 return path + component + sep + base + this.get("suffix");
4133 };
4134
4135 exports.setModuleUrl = function(name, subst) {
4136 return options.$moduleUrls[name] = subst;
4137 };
4138
4139 exports.$loading = {};
4140 exports.loadModule = function(moduleName, onLoad) {
4141 var module, moduleType;
4142 if (Array.isArray(moduleName)) {
4143 moduleType = moduleName[0];
4144 moduleName = moduleName[1];
4145 }
4146
4147 try {
4148 module = require(moduleName);
4149 } catch (e) {}
4150 if (module && !exports.$loading[moduleName])
4151 return onLoad && onLoad(module);
4152
4153 if (!exports.$loading[moduleName])
4154 exports.$loading[moduleName] = [];
4155
4156 exports.$loading[moduleName].push(onLoad);
4157
4158 if (exports.$loading[moduleName].length > 1)
4159 return;
4160
4161 var afterLoad = function() {
4162 require([moduleName], function(module) {
4163 exports._emit("load.module", {name: moduleName, module: module});
4164 var listeners = exports.$loading[moduleName];
4165 exports.$loading[moduleName] = null;
4166 listeners.forEach(function(onLoad) {
4167 onLoad && onLoad(module);
4168 });
4169 });
4170 };
4171
4172 if (!exports.get("packaged"))
4173 return afterLoad();
4174 net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
4175 };
4176 init(true);function init(packaged) {
4177
4178 if (!global || !global.document)
4179 return;
4180
4181 options.packaged = packaged || require.packaged || module.packaged || (global.define && define.packaged);
4182
4183 var scriptOptions = {};
4184 var scriptUrl = "";
4185 var currentScript = (document.currentScript || document._currentScript ); // native or polyfill
4186 var currentDocument = currentScript && currentScript.ownerDocument || document;
4187
4188 var scripts = currentDocument.getElementsByTagName("script");
4189 for (var i=0; i<scripts.length; i++) {
4190 var script = scripts[i];
4191
4192 var src = script.src || script.getAttribute("src");
4193 if (!src)
4194 continue;
4195
4196 var attributes = script.attributes;
4197 for (var j=0, l=attributes.length; j < l; j++) {
4198 var attr = attributes[j];
4199 if (attr.name.indexOf("data-ace-") === 0) {
4200 scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
4201 }
4202 }
4203
4204 var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
4205 if (m)
4206 scriptUrl = m[1];
4207 }
4208
4209 if (scriptUrl) {
4210 scriptOptions.base = scriptOptions.base || scriptUrl;
4211 scriptOptions.packaged = true;
4212 }
4213
4214 scriptOptions.basePath = scriptOptions.base;
4215 scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
4216 scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
4217 scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
4218 delete scriptOptions.base;
4219
4220 for (var key in scriptOptions)
4221 if (typeof scriptOptions[key] !== "undefined")
4222 exports.set(key, scriptOptions[key]);
4223 }
4224
4225 exports.init = init;
4226
4227 function deHyphenate(str) {
4228 return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
4229 }
4230
4231 });
4232
4233 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(require, exports, module) {
4234 "use strict";
4235
4236 var event = require("../lib/event");
4237 var useragent = require("../lib/useragent");
4238 var DefaultHandlers = require("./default_handlers").DefaultHandlers;
4239 var DefaultGutterHandler = require("./default_gutter_handler").GutterHandler;
4240 var MouseEvent = require("./mouse_event").MouseEvent;
4241 var DragdropHandler = require("./dragdrop_handler").DragdropHandler;
4242 var config = require("../config");
4243
4244 var MouseHandler = function(editor) {
4245 var _self = this;
4246 this.editor = editor;
4247
4248 new DefaultHandlers(this);
4249 new DefaultGutterHandler(this);
4250 new DragdropHandler(this);
4251
4252 var focusEditor = function(e) {
4253 var windowBlurred = !document.hasFocus || !document.hasFocus()
4254 || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement());
4255 if (windowBlurred)
4256 window.focus();
4257 editor.focus();
4258 };
4259
4260 var mouseTarget = editor.renderer.getMouseEventTarget();
4261 event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
4262 event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
4263 event.addMultiMouseDownListener([
4264 mouseTarget,
4265 editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner,
4266 editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner,
4267 editor.textInput && editor.textInput.getElement()
4268 ].filter(Boolean), [400, 300, 250], this, "onMouseEvent");
4269 event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
4270 event.addTouchMoveListener(editor.container, this.onTouchMove.bind(this, "touchmove"));
4271
4272 var gutterEl = editor.renderer.$gutter;
4273 event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
4274 event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
4275 event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
4276 event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
4277
4278 event.addListener(mouseTarget, "mousedown", focusEditor);
4279 event.addListener(gutterEl, "mousedown", focusEditor);
4280 if (useragent.isIE && editor.renderer.scrollBarV) {
4281 event.addListener(editor.renderer.scrollBarV.element, "mousedown", focusEditor);
4282 event.addListener(editor.renderer.scrollBarH.element, "mousedown", focusEditor);
4283 }
4284
4285 editor.on("mousemove", function(e){
4286 if (_self.state || _self.$dragDelay || !_self.$dragEnabled)
4287 return;
4288
4289 var character = editor.renderer.screenToTextCoordinates(e.x, e.y);
4290 var range = editor.session.selection.getRange();
4291 var renderer = editor.renderer;
4292
4293 if (!range.isEmpty() && range.insideStart(character.row, character.column)) {
4294 renderer.setCursorStyle("default");
4295 } else {
4296 renderer.setCursorStyle("");
4297 }
4298 });
4299 };
4300
4301 (function() {
4302 this.onMouseEvent = function(name, e) {
4303 this.editor._emit(name, new MouseEvent(e, this.editor));
4304 };
4305
4306 this.onMouseMove = function(name, e) {
4307 var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
4308 if (!listeners || !listeners.length)
4309 return;
4310
4311 this.editor._emit(name, new MouseEvent(e, this.editor));
4312 };
4313
4314 this.onMouseWheel = function(name, e) {
4315 var mouseEvent = new MouseEvent(e, this.editor);
4316 mouseEvent.speed = this.$scrollSpeed * 2;
4317 mouseEvent.wheelX = e.wheelX;
4318 mouseEvent.wheelY = e.wheelY;
4319
4320 this.editor._emit(name, mouseEvent);
4321 };
4322
4323 this.onTouchMove = function (name, e) {
4324 var mouseEvent = new MouseEvent(e, this.editor);
4325 mouseEvent.speed = 1;//this.$scrollSpeed * 2;
4326 mouseEvent.wheelX = e.wheelX;
4327 mouseEvent.wheelY = e.wheelY;
4328 this.editor._emit(name, mouseEvent);
4329 };
4330
4331 this.setState = function(state) {
4332 this.state = state;
4333 };
4334
4335 this.captureMouse = function(ev, mouseMoveHandler) {
4336 this.x = ev.x;
4337 this.y = ev.y;
4338
4339 this.isMousePressed = true;
4340 var renderer = this.editor.renderer;
4341 if (renderer.$keepTextAreaAtCursor)
4342 renderer.$keepTextAreaAtCursor = null;
4343
4344 var self = this;
4345 var onMouseMove = function(e) {
4346 if (!e) return;
4347 if (useragent.isWebKit && !e.which && self.releaseMouse)
4348 return self.releaseMouse();
4349
4350 self.x = e.clientX;
4351 self.y = e.clientY;
4352 mouseMoveHandler && mouseMoveHandler(e);
4353 self.mouseEvent = new MouseEvent(e, self.editor);
4354 self.$mouseMoved = true;
4355 };
4356
4357 var onCaptureEnd = function(e) {
4358 clearInterval(timerId);
4359 onCaptureInterval();
4360 self[self.state + "End"] && self[self.state + "End"](e);
4361 self.state = "";
4362 if (renderer.$keepTextAreaAtCursor == null) {
4363 renderer.$keepTextAreaAtCursor = true;
4364 renderer.$moveTextAreaToCursor();
4365 }
4366 self.isMousePressed = false;
4367 self.$onCaptureMouseMove = self.releaseMouse = null;
4368 e && self.onMouseEvent("mouseup", e);
4369 };
4370
4371 var onCaptureInterval = function() {
4372 self[self.state] && self[self.state]();
4373 self.$mouseMoved = false;
4374 };
4375
4376 if (useragent.isOldIE && ev.domEvent.type == "dblclick") {
4377 return setTimeout(function() {onCaptureEnd(ev);});
4378 }
4379
4380 self.$onCaptureMouseMove = onMouseMove;
4381 self.releaseMouse = event.capture(this.editor.container, onMouseMove, onCaptureEnd);
4382 var timerId = setInterval(onCaptureInterval, 20);
4383 };
4384 this.releaseMouse = null;
4385 this.cancelContextMenu = function() {
4386 var stop = function(e) {
4387 if (e && e.domEvent && e.domEvent.type != "contextmenu")
4388 return;
4389 this.editor.off("nativecontextmenu", stop);
4390 if (e && e.domEvent)
4391 event.stopEvent(e.domEvent);
4392 }.bind(this);
4393 setTimeout(stop, 10);
4394 this.editor.on("nativecontextmenu", stop);
4395 };
4396 }).call(MouseHandler.prototype);
4397
4398 config.defineOptions(MouseHandler.prototype, "mouseHandler", {
4399 scrollSpeed: {initialValue: 2},
4400 dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},
4401 dragEnabled: {initialValue: true},
4402 focusTimout: {initialValue: 0},
4403 tooltipFollowsMouse: {initialValue: true}
4404 });
4405
4406
4407 exports.MouseHandler = MouseHandler;
4408 });
4409
4410 define("ace/mouse/fold_handler",["require","exports","module"], function(require, exports, module) {
4411 "use strict";
4412
4413 function FoldHandler(editor) {
4414
4415 editor.on("click", function(e) {
4416 var position = e.getDocumentPosition();
4417 var session = editor.session;
4418 var fold = session.getFoldAt(position.row, position.column, 1);
4419 if (fold) {
4420 if (e.getAccelKey())
4421 session.removeFold(fold);
4422 else
4423 session.expandFold(fold);
4424
4425 e.stop();
4426 }
4427 });
4428
4429 editor.on("gutterclick", function(e) {
4430 var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4431
4432 if (gutterRegion == "foldWidgets") {
4433 var row = e.getDocumentPosition().row;
4434 var session = editor.session;
4435 if (session.foldWidgets && session.foldWidgets[row])
4436 editor.session.onFoldWidgetClick(row, e);
4437 if (!editor.isFocused())
4438 editor.focus();
4439 e.stop();
4440 }
4441 });
4442
4443 editor.on("gutterdblclick", function(e) {
4444 var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4445
4446 if (gutterRegion == "foldWidgets") {
4447 var row = e.getDocumentPosition().row;
4448 var session = editor.session;
4449 var data = session.getParentFoldRangeData(row, true);
4450 var range = data.range || data.firstRange;
4451
4452 if (range) {
4453 row = range.start.row;
4454 var fold = session.getFoldAt(row, session.getLine(row).length, 1);
4455
4456 if (fold) {
4457 session.removeFold(fold);
4458 } else {
4459 session.addFold("...", range);
4460 editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
4461 }
4462 }
4463 e.stop();
4464 }
4465 });
4466 }
4467
4468 exports.FoldHandler = FoldHandler;
4469
4470 });
4471
4472 define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"], function(require, exports, module) {
4473 "use strict";
4474
4475 var keyUtil = require("../lib/keys");
4476 var event = require("../lib/event");
4477
4478 var KeyBinding = function(editor) {
4479 this.$editor = editor;
4480 this.$data = {editor: editor};
4481 this.$handlers = [];
4482 this.setDefaultHandler(editor.commands);
4483 };
4484
4485 (function() {
4486 this.setDefaultHandler = function(kb) {
4487 this.removeKeyboardHandler(this.$defaultHandler);
4488 this.$defaultHandler = kb;
4489 this.addKeyboardHandler(kb, 0);
4490 };
4491
4492 this.setKeyboardHandler = function(kb) {
4493 var h = this.$handlers;
4494 if (h[h.length - 1] == kb)
4495 return;
4496
4497 while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler)
4498 this.removeKeyboardHandler(h[h.length - 1]);
4499
4500 this.addKeyboardHandler(kb, 1);
4501 };
4502
4503 this.addKeyboardHandler = function(kb, pos) {
4504 if (!kb)
4505 return;
4506 if (typeof kb == "function" && !kb.handleKeyboard)
4507 kb.handleKeyboard = kb;
4508 var i = this.$handlers.indexOf(kb);
4509 if (i != -1)
4510 this.$handlers.splice(i, 1);
4511
4512 if (pos == undefined)
4513 this.$handlers.push(kb);
4514 else
4515 this.$handlers.splice(pos, 0, kb);
4516
4517 if (i == -1 && kb.attach)
4518 kb.attach(this.$editor);
4519 };
4520
4521 this.removeKeyboardHandler = function(kb) {
4522 var i = this.$handlers.indexOf(kb);
4523 if (i == -1)
4524 return false;
4525 this.$handlers.splice(i, 1);
4526 kb.detach && kb.detach(this.$editor);
4527 return true;
4528 };
4529
4530 this.getKeyboardHandler = function() {
4531 return this.$handlers[this.$handlers.length - 1];
4532 };
4533
4534 this.getStatusText = function() {
4535 var data = this.$data;
4536 var editor = data.editor;
4537 return this.$handlers.map(function(h) {
4538 return h.getStatusText && h.getStatusText(editor, data) || "";
4539 }).filter(Boolean).join(" ");
4540 };
4541
4542 this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) {
4543 var toExecute;
4544 var success = false;
4545 var commands = this.$editor.commands;
4546
4547 for (var i = this.$handlers.length; i--;) {
4548 toExecute = this.$handlers[i].handleKeyboard(
4549 this.$data, hashId, keyString, keyCode, e
4550 );
4551 if (!toExecute || !toExecute.command)
4552 continue;
4553 if (toExecute.command == "null") {
4554 success = true;
4555 } else {
4556 success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
4557 }
4558 if (success && e && hashId != -1 &&
4559 toExecute.passEvent != true && toExecute.command.passEvent != true
4560 ) {
4561 event.stopEvent(e);
4562 }
4563 if (success)
4564 break;
4565 }
4566
4567 if (!success && hashId == -1) {
4568 toExecute = {command: "insertstring"};
4569 success = commands.exec("insertstring", this.$editor, keyString);
4570 }
4571
4572 if (success && this.$editor._signal)
4573 this.$editor._signal("keyboardActivity", toExecute);
4574
4575 return success;
4576 };
4577
4578 this.onCommandKey = function(e, hashId, keyCode) {
4579 var keyString = keyUtil.keyCodeToString(keyCode);
4580 this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
4581 };
4582
4583 this.onTextInput = function(text) {
4584 this.$callKeyboardHandlers(-1, text);
4585 };
4586
4587 }).call(KeyBinding.prototype);
4588
4589 exports.KeyBinding = KeyBinding;
4590 });
4591
4592 define("ace/lib/bidiutil",["require","exports","module"], function(require, exports, module) {
4593 "use strict";
4594
4595 var ArabicAlefBetIntervalsBegine = ['\u0621', '\u0641'];
4596 var ArabicAlefBetIntervalsEnd = ['\u063A', '\u064a'];
4597 var dir = 0, hiLevel = 0;
4598 var lastArabic = false, hasUBAT_AL = false, hasUBAT_B = false, hasUBAT_S = false, hasBlockSep = false, hasSegSep = false;
4599
4600 var 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 ]
4601 ];
4602
4603 var 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 ]
4604 ];
4605
4606 var LTR = 0, RTL = 1;
4607
4608 var L = 0;
4609 var R = 1;
4610 var EN = 2;
4611 var AN = 3;
4612 var ON = 4;
4613 var B = 5;
4614 var S = 6;
4615 var AL = 7;
4616 var WS = 8;
4617 var CS = 9;
4618 var ES = 10;
4619 var ET = 11;
4620 var NSM = 12;
4621 var LRE = 13;
4622 var RLE = 14;
4623 var PDF = 15;
4624 var LRO = 16;
4625 var RLO = 17;
4626 var BN = 18;
4627
4628 var UnicodeTBL00 = [
4629 BN,BN,BN,BN,BN,BN,BN,BN,BN,S,B,S,WS,B,BN,BN,
4630 BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,B,B,B,S,
4631 WS,ON,ON,ET,ET,ET,ON,ON,ON,ON,ON,ES,CS,ES,CS,CS,
4632 EN,EN,EN,EN,EN,EN,EN,EN,EN,EN,CS,ON,ON,ON,ON,ON,
4633 ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,
4634 L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,ON,
4635 ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,
4636 L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,BN,
4637 BN,BN,BN,BN,BN,B,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,
4638 BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,
4639 CS,ON,ET,ET,ET,ET,ON,ON,ON,ON,L,ON,ON,BN,ON,ON,
4640 ET,ET,EN,EN,ON,L,ON,ON,ON,EN,L,ON,ON,ON,ON,ON
4641 ];
4642
4643 var UnicodeTBL20 = [
4644 WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,BN,BN,BN,L,R ,
4645 ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4646 ON,ON,ON,ON,ON,ON,ON,ON,WS,B,LRE,RLE,PDF,LRO,RLO,CS,
4647 ET,ET,ET,ET,ET,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4648 ON,ON,ON,ON,CS,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,
4649 ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,WS
4650 ];
4651
4652 function _computeLevels(chars, levels, len, charTypes) {
4653 var impTab = dir ? impTab_RTL : impTab_LTR
4654 , prevState = null, newClass = null, newLevel = null, newState = 0
4655 , action = null, cond = null, condPos = -1, i = null, ix = null, classes = [];
4656
4657 if (!charTypes) {
4658 for (i = 0, charTypes = []; i < len; i++) {
4659 charTypes[i] = _getCharacterType(chars[i]);
4660 }
4661 }
4662 hiLevel = dir;
4663 lastArabic = false;
4664 hasUBAT_AL = false;
4665 hasUBAT_B = false;
4666 hasUBAT_S = false;
4667 for (ix = 0; ix < len; ix++){
4668 prevState = newState;
4669 classes[ix] = newClass = _getCharClass(chars, charTypes, classes, ix);
4670 newState = impTab[prevState][newClass];
4671 action = newState & 0xF0;
4672 newState &= 0x0F;
4673 levels[ix] = newLevel = impTab[newState][5];
4674 if (action > 0){
4675 if (action == 0x10){
4676 for(i = condPos; i < ix; i++){
4677 levels[i] = 1;
4678 }
4679 condPos = -1;
4680 } else {
4681 condPos = -1;
4682 }
4683 }
4684 cond = impTab[newState][6];
4685 if (cond){
4686 if(condPos == -1){
4687 condPos = ix;
4688 }
4689 }else{
4690 if (condPos > -1){
4691 for(i = condPos; i < ix; i++){
4692 levels[i] = newLevel;
4693 }
4694 condPos = -1;
4695 }
4696 }
4697 if (charTypes[ix] == B){
4698 levels[ix] = 0;
4699 }
4700 hiLevel |= newLevel;
4701 }
4702 if (hasUBAT_S){
4703 for(i = 0; i < len; i++){
4704 if(charTypes[i] == S){
4705 levels[i] = dir;
4706 for(var j = i - 1; j >= 0; j--){
4707 if(charTypes[j] == WS){
4708 levels[j] = dir;
4709 }else{
4710 break;
4711 }
4712 }
4713 }
4714 }
4715 }
4716 }
4717
4718 function _invertLevel(lev, levels, _array) {
4719 if (hiLevel < lev){
4720 return;
4721 }
4722 if (lev == 1 && dir == RTL && !hasUBAT_B){
4723 _array.reverse();
4724 return;
4725 }
4726 var len = _array.length, start = 0, end, lo, hi, tmp;
4727 while(start < len){
4728 if (levels[start] >= lev){
4729 end = start + 1;
4730 while(end < len && levels[end] >= lev){
4731 end++;
4732 }
4733 for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){
4734 tmp = _array[lo];
4735 _array[lo] = _array[hi];
4736 _array[hi] = tmp;
4737 }
4738 start = end;
4739 }
4740 start++;
4741 }
4742 }
4743
4744 function _getCharClass(chars, types, classes, ix) {
4745 var cType = types[ix], wType, nType, len, i;
4746 switch(cType){
4747 case L:
4748 case R:
4749 lastArabic = false;
4750 case ON:
4751 case AN:
4752 return cType;
4753 case EN:
4754 return lastArabic ? AN : EN;
4755 case AL:
4756 lastArabic = true;
4757 hasUBAT_AL = true;
4758 return R;
4759 case WS:
4760 return ON;
4761 case CS:
4762 if (ix < 1 || (ix + 1) >= types.length ||
4763 ((wType = classes[ix - 1]) != EN && wType != AN) ||
4764 ((nType = types[ix + 1]) != EN && nType != AN)){
4765 return ON;
4766 }
4767 if (lastArabic){nType = AN;}
4768 return nType == wType ? nType : ON;
4769 case ES:
4770 wType = ix > 0 ? classes[ix - 1] : B;
4771 if (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){
4772 return EN;
4773 }
4774 return ON;
4775 case ET:
4776 if (ix > 0 && classes[ix - 1] == EN){
4777 return EN;
4778 }
4779 if (lastArabic){
4780 return ON;
4781 }
4782 i = ix + 1;
4783 len = types.length;
4784 while (i < len && types[i] == ET){
4785 i++;
4786 }
4787 if (i < len && types[i] == EN){
4788 return EN;
4789 }
4790 return ON;
4791 case NSM:
4792 len = types.length;
4793 i = ix + 1;
4794 while (i < len && types[i] == NSM){
4795 i++;
4796 }
4797 if (i < len){
4798 var c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E;
4799
4800 wType = types[i];
4801 if (rtlCandidate && (wType == R || wType == AL)){
4802 return R;
4803 }
4804 }
4805
4806 if (ix < 1 || (wType = types[ix - 1]) == B){
4807 return ON;
4808 }
4809 return classes[ix - 1];
4810 case B:
4811 lastArabic = false;
4812 hasUBAT_B = true;
4813 return dir;
4814 case S:
4815 hasUBAT_S = true;
4816 return ON;
4817 case LRE:
4818 case RLE:
4819 case LRO:
4820 case RLO:
4821 case PDF:
4822 lastArabic = false;
4823 case BN:
4824 return ON;
4825 }
4826 }
4827
4828 function _getCharacterType( ch ) {
4829 var uc = ch.charCodeAt(0), hi = uc >> 8;
4830
4831 if (hi == 0) {
4832 return ((uc > 0x00BF) ? L : UnicodeTBL00[uc]);
4833 } else if (hi == 5) {
4834 return (/[\u0591-\u05f4]/.test(ch) ? R : L);
4835 } else if (hi == 6) {
4836 if (/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(ch))
4837 return NSM;
4838 else if (/[\u0660-\u0669\u066b-\u066c]/.test(ch))
4839 return AN;
4840 else if (uc == 0x066A)
4841 return ET;
4842 else if (/[\u06f0-\u06f9]/.test(ch))
4843 return EN;
4844 else
4845 return AL;
4846 } else if (hi == 0x20 && uc <= 0x205F) {
4847 return UnicodeTBL20[uc & 0xFF];
4848 } else if (hi == 0xFE) {
4849 return (uc >= 0xFE70 ? AL : ON);
4850 }
4851 return ON;
4852 }
4853
4854 function _isArabicDiacritics( ch ) {
4855 return (ch >= '\u064b' && ch <= '\u0655');
4856 }
4857 exports.L = L;
4858 exports.R = R;
4859 exports.EN = EN;
4860 exports.ON_R = 3;
4861 exports.AN = 4;
4862 exports.R_H = 5;
4863 exports.B = 6;
4864
4865 exports.DOT = "\xB7";
4866 exports.doBidiReorder = function(text, textCharTypes, isRtl) {
4867 if (text.length < 2)
4868 return {};
4869
4870 var chars = text.split(""), logicalFromVisual = new Array(chars.length),
4871 bidiLevels = new Array(chars.length), levels = [];
4872
4873 dir = isRtl ? RTL : LTR;
4874
4875 _computeLevels(chars, levels, chars.length, textCharTypes);
4876
4877 for (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++);
4878
4879 _invertLevel(2, levels, logicalFromVisual);
4880 _invertLevel(1, levels, logicalFromVisual);
4881
4882 for (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width
4883 if (textCharTypes[i] === AN) {
4884 levels[i] = exports.AN;
4885 } else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE)
4886 || textCharTypes[i] === ON || textCharTypes[i] === BN)) {
4887 levels[i] = exports.ON_R;
4888 } else if ((i > 0 && chars[i - 1] === '\u0644') && /\u0622|\u0623|\u0625|\u0627/.test(chars[i])) {
4889 levels[i - 1] = levels[i] = exports.R_H;
4890 i++;
4891 }
4892 }
4893 if (chars[chars.length - 1] === exports.DOT)
4894 levels[chars.length - 1] = exports.B;
4895
4896 for (var i = 0; i < logicalFromVisual.length; i++) {
4897 bidiLevels[i] = levels[logicalFromVisual[i]];
4898 }
4899
4900 return {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels};
4901 };
4902 exports.hasBidiCharacters = function(text, textCharTypes){
4903 var ret = false;
4904 for (var i = 0; i < text.length; i++){
4905 textCharTypes[i] = _getCharacterType(text.charAt(i));
4906 if (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL))
4907 ret = true;
4908 }
4909 return ret;
4910 };
4911 exports.getVisualFromLogicalIdx = function(logIdx, rowMap) {
4912 for (var i = 0; i < rowMap.logicalFromVisual.length; i++) {
4913 if (rowMap.logicalFromVisual[i] == logIdx)
4914 return i;
4915 }
4916 return 0;
4917 };
4918
4919 });
4920
4921 define("ace/bidihandler",["require","exports","module","ace/lib/bidiutil","ace/lib/lang","ace/lib/useragent"], function(require, exports, module) {
4922 "use strict";
4923
4924 var bidiUtil = require("./lib/bidiutil");
4925 var lang = require("./lib/lang");
4926 var useragent = require("./lib/useragent");
4927 var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
4928 var BidiHandler = function(session) {
4929 this.session = session;
4930 this.bidiMap = {};
4931 this.currentRow = null;
4932 this.bidiUtil = bidiUtil;
4933 this.charWidths = [];
4934 this.EOL = "\xAC";
4935 this.showInvisibles = true;
4936 this.isRtlDir = false;
4937 this.line = "";
4938 this.wrapIndent = 0;
4939 this.isLastRow = false;
4940 this.EOF = "\xB6";
4941 this.seenBidi = false;
4942 };
4943
4944 (function() {
4945 this.isBidiRow = function(screenRow, docRow, splitIndex) {
4946 if (!this.seenBidi)
4947 return false;
4948 if (screenRow !== this.currentRow) {
4949 this.currentRow = screenRow;
4950 this.updateRowLine(docRow, splitIndex);
4951 this.updateBidiMap();
4952 }
4953 return this.bidiMap.bidiLevels;
4954 };
4955
4956 this.onChange = function(delta) {
4957 if (!this.seenBidi) {
4958 if (delta.action == "insert" && bidiRE.test(delta.lines.join("\n"))) {
4959 this.seenBidi = true;
4960 this.currentRow = null;
4961 }
4962 }
4963 else {
4964 this.currentRow = null;
4965 }
4966 };
4967
4968 this.getDocumentRow = function() {
4969 var docRow = 0;
4970 var rowCache = this.session.$screenRowCache;
4971 if (rowCache.length) {
4972 var index = this.session.$getRowCacheIndex(rowCache, this.currentRow);
4973 if (index >= 0)
4974 docRow = this.session.$docRowCache[index];
4975 }
4976
4977 return docRow;
4978 };
4979
4980 this.getSplitIndex = function() {
4981 var splitIndex = 0;
4982 var rowCache = this.session.$screenRowCache;
4983 if (rowCache.length) {
4984 var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow);
4985 while (this.currentRow - splitIndex > 0) {
4986 currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1);
4987 if (currentIndex !== prevIndex)
4988 break;
4989
4990 prevIndex = currentIndex;
4991 splitIndex++;
4992 }
4993 }
4994
4995 return splitIndex;
4996 };
4997
4998 this.updateRowLine = function(docRow, splitIndex) {
4999 if (docRow === undefined)
5000 docRow = this.getDocumentRow();
5001
5002 this.wrapIndent = 0;
5003 this.isLastRow = (docRow === this.session.getLength() - 1);
5004 this.line = this.session.getLine(docRow);
5005 if (this.session.$useWrapMode) {
5006 var splits = this.session.$wrapData[docRow];
5007 if (splits) {
5008 if (splitIndex === undefined)
5009 splitIndex = this.getSplitIndex();
5010
5011 if(splitIndex > 0 && splits.length) {
5012 this.wrapIndent = splits.indent;
5013 this.line = (splitIndex < splits.length) ?
5014 this.line.substring(splits[splitIndex - 1], splits[splits.length - 1]) :
5015 this.line.substring(splits[splits.length - 1]);
5016 } else {
5017 this.line = this.line.substring(0, splits[splitIndex]);
5018 }
5019 }
5020 }
5021 var session = this.session, shift = 0, size;
5022 this.line = this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g, function(ch, i){
5023 if (ch === '\t' || session.isFullWidth(ch.charCodeAt(0))) {
5024 size = (ch === '\t') ? session.getScreenTabSize(i + shift) : 2;
5025 shift += size - 1;
5026 return lang.stringRepeat(bidiUtil.DOT, size);
5027 }
5028 return ch;
5029 });
5030 };
5031
5032 this.updateBidiMap = function() {
5033 var textCharTypes = [], endOfLine = this.isLastRow ? this.EOF : this.EOL;
5034 var line = this.line + (this.showInvisibles ? endOfLine : bidiUtil.DOT);
5035 if (bidiUtil.hasBidiCharacters(line, textCharTypes)) {
5036 this.bidiMap = bidiUtil.doBidiReorder(line, textCharTypes, this.isRtlDir);
5037 } else {
5038 this.bidiMap = {};
5039 }
5040 };
5041 this.markAsDirty = function() {
5042 this.currentRow = null;
5043 };
5044 this.updateCharacterWidths = function(fontMetrics) {
5045 if (!this.seenBidi)
5046 return;
5047 if (this.characterWidth === fontMetrics.$characterSize.width)
5048 return;
5049
5050 var characterWidth = this.characterWidth = fontMetrics.$characterSize.width;
5051 var bidiCharWidth = fontMetrics.$measureCharWidth("\u05d4");
5052
5053 this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth;
5054 this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth;
5055 this.charWidths[bidiUtil.R_H] = useragent.isChrome ? bidiCharWidth : bidiCharWidth * 0.45;
5056 this.charWidths[bidiUtil.B] = 0;
5057
5058 this.currentRow = null;
5059 };
5060
5061 this.getShowInvisibles = function() {
5062 return this.showInvisibles;
5063 };
5064
5065 this.setShowInvisibles = function(showInvisibles) {
5066 this.showInvisibles = showInvisibles;
5067 this.currentRow = null;
5068 };
5069
5070 this.setEolChar = function(eolChar) {
5071 this.EOL = eolChar;
5072 };
5073
5074 this.setTextDir = function(isRtlDir) {
5075 this.isRtlDir = isRtlDir;
5076 };
5077 this.getPosLeft = function(col) {
5078 col -= this.wrapIndent;
5079 var visualIdx = bidiUtil.getVisualFromLogicalIdx(col > 0 ? col - 1 : 0, this.bidiMap),
5080 levels = this.bidiMap.bidiLevels, left = 0;
5081
5082 if (col === 0 && levels[visualIdx] % 2 !== 0)
5083 visualIdx++;
5084
5085 for (var i = 0; i < visualIdx; i++) {
5086 left += this.charWidths[levels[i]];
5087 }
5088
5089 if (col !== 0 && levels[visualIdx] % 2 === 0)
5090 left += this.charWidths[levels[visualIdx]];
5091
5092 if (this.wrapIndent)
5093 left += this.wrapIndent * this.charWidths[bidiUtil.L];
5094
5095 return left;
5096 };
5097 this.getSelections = function(startCol, endCol) {
5098 var map = this.bidiMap, levels = map.bidiLevels, level, offset = this.wrapIndent * this.charWidths[bidiUtil.L], selections = [],
5099 selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent,
5100 isSelected = false, isSelectedPrev = false, selectionStart = 0;
5101
5102 for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) {
5103 logIdx = map.logicalFromVisual[visIdx];
5104 level = levels[visIdx];
5105 isSelected = (logIdx >= selColMin) && (logIdx < selColMax);
5106 if (isSelected && !isSelectedPrev) {
5107 selectionStart = offset;
5108 } else if (!isSelected && isSelectedPrev) {
5109 selections.push({left: selectionStart, width: offset - selectionStart});
5110 }
5111 offset += this.charWidths[level];
5112 isSelectedPrev = isSelected;
5113 }
5114
5115 if (isSelected && (visIdx === levels.length)) {
5116 selections.push({left: selectionStart, width: offset - selectionStart});
5117 }
5118
5119 return selections;
5120 };
5121 this.offsetToCol = function(posX) {
5122 var logicalIdx = 0, posX = Math.max(posX, 0),
5123 offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels,
5124 charWidth = this.charWidths[levels[visualIdx]];
5125
5126 if (this.wrapIndent) {
5127 posX -= this.wrapIndent * this.charWidths[bidiUtil.L];
5128 }
5129
5130 while(posX > offset + charWidth/2) {
5131 offset += charWidth;
5132 if(visualIdx === levels.length - 1) {
5133 charWidth = 0;
5134 break;
5135 }
5136 charWidth = this.charWidths[levels[++visualIdx]];
5137 }
5138
5139 if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){
5140 if(posX < offset)
5141 visualIdx--;
5142 logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];
5143
5144 } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){
5145 logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx]
5146 : this.bidiMap.logicalFromVisual[visualIdx - 1]);
5147
5148 } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0))
5149 || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){
5150 logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx];
5151 } else {
5152 if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0)
5153 visualIdx--;
5154 logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];
5155 }
5156
5157 return (logicalIdx + this.wrapIndent);
5158 };
5159
5160 }).call(BidiHandler.prototype);
5161
5162 exports.BidiHandler = BidiHandler;
5163 });
5164
5165 define("ace/range",["require","exports","module"], function(require, exports, module) {
5166 "use strict";
5167 var comparePoints = function(p1, p2) {
5168 return p1.row - p2.row || p1.column - p2.column;
5169 };
5170 var Range = function(startRow, startColumn, endRow, endColumn) {
5171 this.start = {
5172 row: startRow,
5173 column: startColumn
5174 };
5175
5176 this.end = {
5177 row: endRow,
5178 column: endColumn
5179 };
5180 };
5181
5182 (function() {
5183 this.isEqual = function(range) {
5184 return this.start.row === range.start.row &&
5185 this.end.row === range.end.row &&
5186 this.start.column === range.start.column &&
5187 this.end.column === range.end.column;
5188 };
5189 this.toString = function() {
5190 return ("Range: [" + this.start.row + "/" + this.start.column +
5191 "] -> [" + this.end.row + "/" + this.end.column + "]");
5192 };
5193
5194 this.contains = function(row, column) {
5195 return this.compare(row, column) == 0;
5196 };
5197 this.compareRange = function(range) {
5198 var cmp,
5199 end = range.end,
5200 start = range.start;
5201
5202 cmp = this.compare(end.row, end.column);
5203 if (cmp == 1) {
5204 cmp = this.compare(start.row, start.column);
5205 if (cmp == 1) {
5206 return 2;
5207 } else if (cmp == 0) {
5208 return 1;
5209 } else {
5210 return 0;
5211 }
5212 } else if (cmp == -1) {
5213 return -2;
5214 } else {
5215 cmp = this.compare(start.row, start.column);
5216 if (cmp == -1) {
5217 return -1;
5218 } else if (cmp == 1) {
5219 return 42;
5220 } else {
5221 return 0;
5222 }
5223 }
5224 };
5225 this.comparePoint = function(p) {
5226 return this.compare(p.row, p.column);
5227 };
5228 this.containsRange = function(range) {
5229 return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
5230 };
5231 this.intersects = function(range) {
5232 var cmp = this.compareRange(range);
5233 return (cmp == -1 || cmp == 0 || cmp == 1);
5234 };
5235 this.isEnd = function(row, column) {
5236 return this.end.row == row && this.end.column == column;
5237 };
5238 this.isStart = function(row, column) {
5239 return this.start.row == row && this.start.column == column;
5240 };
5241 this.setStart = function(row, column) {
5242 if (typeof row == "object") {
5243 this.start.column = row.column;
5244 this.start.row = row.row;
5245 } else {
5246 this.start.row = row;
5247 this.start.column = column;
5248 }
5249 };
5250 this.setEnd = function(row, column) {
5251 if (typeof row == "object") {
5252 this.end.column = row.column;
5253 this.end.row = row.row;
5254 } else {
5255 this.end.row = row;
5256 this.end.column = column;
5257 }
5258 };
5259 this.inside = function(row, column) {
5260 if (this.compare(row, column) == 0) {
5261 if (this.isEnd(row, column) || this.isStart(row, column)) {
5262 return false;
5263 } else {
5264 return true;
5265 }
5266 }
5267 return false;
5268 };
5269 this.insideStart = function(row, column) {
5270 if (this.compare(row, column) == 0) {
5271 if (this.isEnd(row, column)) {
5272 return false;
5273 } else {
5274 return true;
5275 }
5276 }
5277 return false;
5278 };
5279 this.insideEnd = function(row, column) {
5280 if (this.compare(row, column) == 0) {
5281 if (this.isStart(row, column)) {
5282 return false;
5283 } else {
5284 return true;
5285 }
5286 }
5287 return false;
5288 };
5289 this.compare = function(row, column) {
5290 if (!this.isMultiLine()) {
5291 if (row === this.start.row) {
5292 return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
5293 }
5294 }
5295
5296 if (row < this.start.row)
5297 return -1;
5298
5299 if (row > this.end.row)
5300 return 1;
5301
5302 if (this.start.row === row)
5303 return column >= this.start.column ? 0 : -1;
5304
5305 if (this.end.row === row)
5306 return column <= this.end.column ? 0 : 1;
5307
5308 return 0;
5309 };
5310 this.compareStart = function(row, column) {
5311 if (this.start.row == row && this.start.column == column) {
5312 return -1;
5313 } else {
5314 return this.compare(row, column);
5315 }
5316 };
5317 this.compareEnd = function(row, column) {
5318 if (this.end.row == row && this.end.column == column) {
5319 return 1;
5320 } else {
5321 return this.compare(row, column);
5322 }
5323 };
5324 this.compareInside = function(row, column) {
5325 if (this.end.row == row && this.end.column == column) {
5326 return 1;
5327 } else if (this.start.row == row && this.start.column == column) {
5328 return -1;
5329 } else {
5330 return this.compare(row, column);
5331 }
5332 };
5333 this.clipRows = function(firstRow, lastRow) {
5334 if (this.end.row > lastRow)
5335 var end = {row: lastRow + 1, column: 0};
5336 else if (this.end.row < firstRow)
5337 var end = {row: firstRow, column: 0};
5338
5339 if (this.start.row > lastRow)
5340 var start = {row: lastRow + 1, column: 0};
5341 else if (this.start.row < firstRow)
5342 var start = {row: firstRow, column: 0};
5343
5344 return Range.fromPoints(start || this.start, end || this.end);
5345 };
5346 this.extend = function(row, column) {
5347 var cmp = this.compare(row, column);
5348
5349 if (cmp == 0)
5350 return this;
5351 else if (cmp == -1)
5352 var start = {row: row, column: column};
5353 else
5354 var end = {row: row, column: column};
5355
5356 return Range.fromPoints(start || this.start, end || this.end);
5357 };
5358
5359 this.isEmpty = function() {
5360 return (this.start.row === this.end.row && this.start.column === this.end.column);
5361 };
5362 this.isMultiLine = function() {
5363 return (this.start.row !== this.end.row);
5364 };
5365 this.clone = function() {
5366 return Range.fromPoints(this.start, this.end);
5367 };
5368 this.collapseRows = function() {
5369 if (this.end.column == 0)
5370 return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);
5371 else
5372 return new Range(this.start.row, 0, this.end.row, 0);
5373 };
5374 this.toScreenRange = function(session) {
5375 var screenPosStart = session.documentToScreenPosition(this.start);
5376 var screenPosEnd = session.documentToScreenPosition(this.end);
5377
5378 return new Range(
5379 screenPosStart.row, screenPosStart.column,
5380 screenPosEnd.row, screenPosEnd.column
5381 );
5382 };
5383 this.moveBy = function(row, column) {
5384 this.start.row += row;
5385 this.start.column += column;
5386 this.end.row += row;
5387 this.end.column += column;
5388 };
5389
5390 }).call(Range.prototype);
5391 Range.fromPoints = function(start, end) {
5392 return new Range(start.row, start.column, end.row, end.column);
5393 };
5394 Range.comparePoints = comparePoints;
5395
5396 Range.comparePoints = function(p1, p2) {
5397 return p1.row - p2.row || p1.column - p2.column;
5398 };
5399
5400
5401 exports.Range = Range;
5402 });
5403
5404 define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"], function(require, exports, module) {
5405 "use strict";
5406
5407 var oop = require("./lib/oop");
5408 var lang = require("./lib/lang");
5409 var EventEmitter = require("./lib/event_emitter").EventEmitter;
5410 var Range = require("./range").Range;
5411 var Selection = function(session) {
5412 this.session = session;
5413 this.doc = session.getDocument();
5414
5415 this.clearSelection();
5416 this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
5417 this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
5418
5419 var self = this;
5420 this.lead.on("change", function(e) {
5421 self._emit("changeCursor");
5422 if (!self.$isEmpty)
5423 self._emit("changeSelection");
5424 if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)
5425 self.$desiredColumn = null;
5426 });
5427
5428 this.selectionAnchor.on("change", function() {
5429 if (!self.$isEmpty)
5430 self._emit("changeSelection");
5431 });
5432 };
5433
5434 (function() {
5435
5436 oop.implement(this, EventEmitter);
5437 this.isEmpty = function() {
5438 return (this.$isEmpty || (
5439 this.anchor.row == this.lead.row &&
5440 this.anchor.column == this.lead.column
5441 ));
5442 };
5443 this.isMultiLine = function() {
5444 if (this.isEmpty()) {
5445 return false;
5446 }
5447
5448 return this.getRange().isMultiLine();
5449 };
5450 this.getCursor = function() {
5451 return this.lead.getPosition();
5452 };
5453 this.setSelectionAnchor = function(row, column) {
5454 this.anchor.setPosition(row, column);
5455
5456 if (this.$isEmpty) {
5457 this.$isEmpty = false;
5458 this._emit("changeSelection");
5459 }
5460 };
5461 this.getSelectionAnchor = function() {
5462 if (this.$isEmpty)
5463 return this.getSelectionLead();
5464 else
5465 return this.anchor.getPosition();
5466 };
5467 this.getSelectionLead = function() {
5468 return this.lead.getPosition();
5469 };
5470 this.shiftSelection = function(columns) {
5471 if (this.$isEmpty) {
5472 this.moveCursorTo(this.lead.row, this.lead.column + columns);
5473 return;
5474 }
5475
5476 var anchor = this.getSelectionAnchor();
5477 var lead = this.getSelectionLead();
5478
5479 var isBackwards = this.isBackwards();
5480
5481 if (!isBackwards || anchor.column !== 0)
5482 this.setSelectionAnchor(anchor.row, anchor.column + columns);
5483
5484 if (isBackwards || lead.column !== 0) {
5485 this.$moveSelection(function() {
5486 this.moveCursorTo(lead.row, lead.column + columns);
5487 });
5488 }
5489 };
5490 this.isBackwards = function() {
5491 var anchor = this.anchor;
5492 var lead = this.lead;
5493 return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
5494 };
5495 this.getRange = function() {
5496 var anchor = this.anchor;
5497 var lead = this.lead;
5498
5499 if (this.isEmpty())
5500 return Range.fromPoints(lead, lead);
5501
5502 if (this.isBackwards()) {
5503 return Range.fromPoints(lead, anchor);
5504 }
5505 else {
5506 return Range.fromPoints(anchor, lead);
5507 }
5508 };
5509 this.clearSelection = function() {
5510 if (!this.$isEmpty) {
5511 this.$isEmpty = true;
5512 this._emit("changeSelection");
5513 }
5514 };
5515 this.selectAll = function() {
5516 var lastRow = this.doc.getLength() - 1;
5517 this.setSelectionAnchor(0, 0);
5518 this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);
5519 };
5520 this.setRange =
5521 this.setSelectionRange = function(range, reverse) {
5522 if (reverse) {
5523 this.setSelectionAnchor(range.end.row, range.end.column);
5524 this.selectTo(range.start.row, range.start.column);
5525 } else {
5526 this.setSelectionAnchor(range.start.row, range.start.column);
5527 this.selectTo(range.end.row, range.end.column);
5528 }
5529 if (this.getRange().isEmpty())
5530 this.$isEmpty = true;
5531 this.$desiredColumn = null;
5532 };
5533
5534 this.$moveSelection = function(mover) {
5535 var lead = this.lead;
5536 if (this.$isEmpty)
5537 this.setSelectionAnchor(lead.row, lead.column);
5538
5539 mover.call(this);
5540 };
5541 this.selectTo = function(row, column) {
5542 this.$moveSelection(function() {
5543 this.moveCursorTo(row, column);
5544 });
5545 };
5546 this.selectToPosition = function(pos) {
5547 this.$moveSelection(function() {
5548 this.moveCursorToPosition(pos);
5549 });
5550 };
5551 this.moveTo = function(row, column) {
5552 this.clearSelection();
5553 this.moveCursorTo(row, column);
5554 };
5555 this.moveToPosition = function(pos) {
5556 this.clearSelection();
5557 this.moveCursorToPosition(pos);
5558 };
5559 this.selectUp = function() {
5560 this.$moveSelection(this.moveCursorUp);
5561 };
5562 this.selectDown = function() {
5563 this.$moveSelection(this.moveCursorDown);
5564 };
5565 this.selectRight = function() {
5566 this.$moveSelection(this.moveCursorRight);
5567 };
5568 this.selectLeft = function() {
5569 this.$moveSelection(this.moveCursorLeft);
5570 };
5571 this.selectLineStart = function() {
5572 this.$moveSelection(this.moveCursorLineStart);
5573 };
5574 this.selectLineEnd = function() {
5575 this.$moveSelection(this.moveCursorLineEnd);
5576 };
5577 this.selectFileEnd = function() {
5578 this.$moveSelection(this.moveCursorFileEnd);
5579 };
5580 this.selectFileStart = function() {
5581 this.$moveSelection(this.moveCursorFileStart);
5582 };
5583 this.selectWordRight = function() {
5584 this.$moveSelection(this.moveCursorWordRight);
5585 };
5586 this.selectWordLeft = function() {
5587 this.$moveSelection(this.moveCursorWordLeft);
5588 };
5589 this.getWordRange = function(row, column) {
5590 if (typeof column == "undefined") {
5591 var cursor = row || this.lead;
5592 row = cursor.row;
5593 column = cursor.column;
5594 }
5595 return this.session.getWordRange(row, column);
5596 };
5597 this.selectWord = function() {
5598 this.setSelectionRange(this.getWordRange());
5599 };
5600 this.selectAWord = function() {
5601 var cursor = this.getCursor();
5602 var range = this.session.getAWordRange(cursor.row, cursor.column);
5603 this.setSelectionRange(range);
5604 };
5605
5606 this.getLineRange = function(row, excludeLastChar) {
5607 var rowStart = typeof row == "number" ? row : this.lead.row;
5608 var rowEnd;
5609
5610 var foldLine = this.session.getFoldLine(rowStart);
5611 if (foldLine) {
5612 rowStart = foldLine.start.row;
5613 rowEnd = foldLine.end.row;
5614 } else {
5615 rowEnd = rowStart;
5616 }
5617 if (excludeLastChar === true)
5618 return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
5619 else
5620 return new Range(rowStart, 0, rowEnd + 1, 0);
5621 };
5622 this.selectLine = function() {
5623 this.setSelectionRange(this.getLineRange());
5624 };
5625 this.moveCursorUp = function() {
5626 this.moveCursorBy(-1, 0);
5627 };
5628 this.moveCursorDown = function() {
5629 this.moveCursorBy(1, 0);
5630 };
5631 this.wouldMoveIntoSoftTab = function(cursor, tabSize, direction) {
5632 var start = cursor.column;
5633 var end = cursor.column + tabSize;
5634
5635 if (direction < 0) {
5636 start = cursor.column - tabSize;
5637 end = cursor.column;
5638 }
5639 return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(" ").length-1 == tabSize;
5640 };
5641 this.moveCursorLeft = function() {
5642 var cursor = this.lead.getPosition(),
5643 fold;
5644
5645 if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
5646 this.moveCursorTo(fold.start.row, fold.start.column);
5647 } else if (cursor.column === 0) {
5648 if (cursor.row > 0) {
5649 this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
5650 }
5651 }
5652 else {
5653 var tabSize = this.session.getTabSize();
5654 if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) {
5655 this.moveCursorBy(0, -tabSize);
5656 } else {
5657 this.moveCursorBy(0, -1);
5658 }
5659 }
5660 };
5661 this.moveCursorRight = function() {
5662 var cursor = this.lead.getPosition(),
5663 fold;
5664 if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
5665 this.moveCursorTo(fold.end.row, fold.end.column);
5666 }
5667 else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
5668 if (this.lead.row < this.doc.getLength() - 1) {
5669 this.moveCursorTo(this.lead.row + 1, 0);
5670 }
5671 }
5672 else {
5673 var tabSize = this.session.getTabSize();
5674 var cursor = this.lead;
5675 if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) {
5676 this.moveCursorBy(0, tabSize);
5677 } else {
5678 this.moveCursorBy(0, 1);
5679 }
5680 }
5681 };
5682 this.moveCursorLineStart = function() {
5683 var row = this.lead.row;
5684 var column = this.lead.column;
5685 var screenRow = this.session.documentToScreenRow(row, column);
5686 var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);
5687 var beforeCursor = this.session.getDisplayLine(
5688 row, null, firstColumnPosition.row,
5689 firstColumnPosition.column
5690 );
5691
5692 var leadingSpace = beforeCursor.match(/^\s*/);
5693 if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)
5694 firstColumnPosition.column += leadingSpace[0].length;
5695 this.moveCursorToPosition(firstColumnPosition);
5696 };
5697 this.moveCursorLineEnd = function() {
5698 var lead = this.lead;
5699 var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
5700 if (this.lead.column == lineEnd.column) {
5701 var line = this.session.getLine(lineEnd.row);
5702 if (lineEnd.column == line.length) {
5703 var textEnd = line.search(/\s+$/);
5704 if (textEnd > 0)
5705 lineEnd.column = textEnd;
5706 }
5707 }
5708
5709 this.moveCursorTo(lineEnd.row, lineEnd.column);
5710 };
5711 this.moveCursorFileEnd = function() {
5712 var row = this.doc.getLength() - 1;
5713 var column = this.doc.getLine(row).length;
5714 this.moveCursorTo(row, column);
5715 };
5716 this.moveCursorFileStart = function() {
5717 this.moveCursorTo(0, 0);
5718 };
5719 this.moveCursorLongWordRight = function() {
5720 var row = this.lead.row;
5721 var column = this.lead.column;
5722 var line = this.doc.getLine(row);
5723 var rightOfCursor = line.substring(column);
5724
5725 var match;
5726 this.session.nonTokenRe.lastIndex = 0;
5727 this.session.tokenRe.lastIndex = 0;
5728 var fold = this.session.getFoldAt(row, column, 1);
5729 if (fold) {
5730 this.moveCursorTo(fold.end.row, fold.end.column);
5731 return;
5732 }
5733 if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
5734 column += this.session.nonTokenRe.lastIndex;
5735 this.session.nonTokenRe.lastIndex = 0;
5736 rightOfCursor = line.substring(column);
5737 }
5738 if (column >= line.length) {
5739 this.moveCursorTo(row, line.length);
5740 this.moveCursorRight();
5741 if (row < this.doc.getLength() - 1)
5742 this.moveCursorWordRight();
5743 return;
5744 }
5745 if (match = this.session.tokenRe.exec(rightOfCursor)) {
5746 column += this.session.tokenRe.lastIndex;
5747 this.session.tokenRe.lastIndex = 0;
5748 }
5749
5750 this.moveCursorTo(row, column);
5751 };
5752 this.moveCursorLongWordLeft = function() {
5753 var row = this.lead.row;
5754 var column = this.lead.column;
5755 var fold;
5756 if (fold = this.session.getFoldAt(row, column, -1)) {
5757 this.moveCursorTo(fold.start.row, fold.start.column);
5758 return;
5759 }
5760
5761 var str = this.session.getFoldStringAt(row, column, -1);
5762 if (str == null) {
5763 str = this.doc.getLine(row).substring(0, column);
5764 }
5765
5766 var leftOfCursor = lang.stringReverse(str);
5767 var match;
5768 this.session.nonTokenRe.lastIndex = 0;
5769 this.session.tokenRe.lastIndex = 0;
5770 if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
5771 column -= this.session.nonTokenRe.lastIndex;
5772 leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
5773 this.session.nonTokenRe.lastIndex = 0;
5774 }
5775 if (column <= 0) {
5776 this.moveCursorTo(row, 0);
5777 this.moveCursorLeft();
5778 if (row > 0)
5779 this.moveCursorWordLeft();
5780 return;
5781 }
5782 if (match = this.session.tokenRe.exec(leftOfCursor)) {
5783 column -= this.session.tokenRe.lastIndex;
5784 this.session.tokenRe.lastIndex = 0;
5785 }
5786
5787 this.moveCursorTo(row, column);
5788 };
5789
5790 this.$shortWordEndIndex = function(rightOfCursor) {
5791 var match, index = 0, ch;
5792 var whitespaceRe = /\s/;
5793 var tokenRe = this.session.tokenRe;
5794
5795 tokenRe.lastIndex = 0;
5796 if (match = this.session.tokenRe.exec(rightOfCursor)) {
5797 index = this.session.tokenRe.lastIndex;
5798 } else {
5799 while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
5800 index ++;
5801
5802 if (index < 1) {
5803 tokenRe.lastIndex = 0;
5804 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
5805 tokenRe.lastIndex = 0;
5806 index ++;
5807 if (whitespaceRe.test(ch)) {
5808 if (index > 2) {
5809 index--;
5810 break;
5811 } else {
5812 while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
5813 index ++;
5814 if (index > 2)
5815 break;
5816 }
5817 }
5818 }
5819 }
5820 }
5821 tokenRe.lastIndex = 0;
5822
5823 return index;
5824 };
5825
5826 this.moveCursorShortWordRight = function() {
5827 var row = this.lead.row;
5828 var column = this.lead.column;
5829 var line = this.doc.getLine(row);
5830 var rightOfCursor = line.substring(column);
5831
5832 var fold = this.session.getFoldAt(row, column, 1);
5833 if (fold)
5834 return this.moveCursorTo(fold.end.row, fold.end.column);
5835
5836 if (column == line.length) {
5837 var l = this.doc.getLength();
5838 do {
5839 row++;
5840 rightOfCursor = this.doc.getLine(row);
5841 } while (row < l && /^\s*$/.test(rightOfCursor));
5842
5843 if (!/^\s+/.test(rightOfCursor))
5844 rightOfCursor = "";
5845 column = 0;
5846 }
5847
5848 var index = this.$shortWordEndIndex(rightOfCursor);
5849
5850 this.moveCursorTo(row, column + index);
5851 };
5852
5853 this.moveCursorShortWordLeft = function() {
5854 var row = this.lead.row;
5855 var column = this.lead.column;
5856
5857 var fold;
5858 if (fold = this.session.getFoldAt(row, column, -1))
5859 return this.moveCursorTo(fold.start.row, fold.start.column);
5860
5861 var line = this.session.getLine(row).substring(0, column);
5862 if (column === 0) {
5863 do {
5864 row--;
5865 line = this.doc.getLine(row);
5866 } while (row > 0 && /^\s*$/.test(line));
5867
5868 column = line.length;
5869 if (!/\s+$/.test(line))
5870 line = "";
5871 }
5872
5873 var leftOfCursor = lang.stringReverse(line);
5874 var index = this.$shortWordEndIndex(leftOfCursor);
5875
5876 return this.moveCursorTo(row, column - index);
5877 };
5878
5879 this.moveCursorWordRight = function() {
5880 if (this.session.$selectLongWords)
5881 this.moveCursorLongWordRight();
5882 else
5883 this.moveCursorShortWordRight();
5884 };
5885
5886 this.moveCursorWordLeft = function() {
5887 if (this.session.$selectLongWords)
5888 this.moveCursorLongWordLeft();
5889 else
5890 this.moveCursorShortWordLeft();
5891 };
5892 this.moveCursorBy = function(rows, chars) {
5893 var screenPos = this.session.documentToScreenPosition(
5894 this.lead.row,
5895 this.lead.column
5896 );
5897
5898 var offsetX;
5899
5900 if (chars === 0) {
5901 if (rows !== 0) {
5902 if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) {
5903 offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column);
5904 screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]);
5905 } else {
5906 offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0];
5907 }
5908 }
5909
5910 if (this.$desiredColumn)
5911 screenPos.column = this.$desiredColumn;
5912 else
5913 this.$desiredColumn = screenPos.column;
5914 }
5915
5916 var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);
5917
5918 if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {
5919 if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) {
5920 if (docPos.row > 0 || rows > 0)
5921 docPos.row++;
5922 }
5923 }
5924 this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
5925 };
5926 this.moveCursorToPosition = function(position) {
5927 this.moveCursorTo(position.row, position.column);
5928 };
5929 this.moveCursorTo = function(row, column, keepDesiredColumn) {
5930 var fold = this.session.getFoldAt(row, column, 1);
5931 if (fold) {
5932 row = fold.start.row;
5933 column = fold.start.column;
5934 }
5935
5936 this.$keepDesiredColumnOnChange = true;
5937 var line = this.session.getLine(row);
5938 if (/[\uDC00-\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) {
5939 if (this.lead.row == row && this.lead.column == column + 1)
5940 column = column - 1;
5941 else
5942 column = column + 1;
5943 }
5944 this.lead.setPosition(row, column);
5945 this.$keepDesiredColumnOnChange = false;
5946
5947 if (!keepDesiredColumn)
5948 this.$desiredColumn = null;
5949 };
5950 this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
5951 var pos = this.session.screenToDocumentPosition(row, column);
5952 this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
5953 };
5954 this.detach = function() {
5955 this.lead.detach();
5956 this.anchor.detach();
5957 this.session = this.doc = null;
5958 };
5959
5960 this.fromOrientedRange = function(range) {
5961 this.setSelectionRange(range, range.cursor == range.start);
5962 this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
5963 };
5964
5965 this.toOrientedRange = function(range) {
5966 var r = this.getRange();
5967 if (range) {
5968 range.start.column = r.start.column;
5969 range.start.row = r.start.row;
5970 range.end.column = r.end.column;
5971 range.end.row = r.end.row;
5972 } else {
5973 range = r;
5974 }
5975
5976 range.cursor = this.isBackwards() ? range.start : range.end;
5977 range.desiredColumn = this.$desiredColumn;
5978 return range;
5979 };
5980 this.getRangeOfMovements = function(func) {
5981 var start = this.getCursor();
5982 try {
5983 func(this);
5984 var end = this.getCursor();
5985 return Range.fromPoints(start,end);
5986 } catch(e) {
5987 return Range.fromPoints(start,start);
5988 } finally {
5989 this.moveCursorToPosition(start);
5990 }
5991 };
5992
5993 this.toJSON = function() {
5994 if (this.rangeCount) {
5995 var data = this.ranges.map(function(r) {
5996 var r1 = r.clone();
5997 r1.isBackwards = r.cursor == r.start;
5998 return r1;
5999 });
6000 } else {
6001 var data = this.getRange();
6002 data.isBackwards = this.isBackwards();
6003 }
6004 return data;
6005 };
6006
6007 this.fromJSON = function(data) {
6008 if (data.start == undefined) {
6009 if (this.rangeList) {
6010 this.toSingleRange(data[0]);
6011 for (var i = data.length; i--; ) {
6012 var r = Range.fromPoints(data[i].start, data[i].end);
6013 if (data[i].isBackwards)
6014 r.cursor = r.start;
6015 this.addRange(r, true);
6016 }
6017 return;
6018 } else
6019 data = data[0];
6020 }
6021 if (this.rangeList)
6022 this.toSingleRange(data);
6023 this.setSelectionRange(data, data.isBackwards);
6024 };
6025
6026 this.isEqual = function(data) {
6027 if ((data.length || this.rangeCount) && data.length != this.rangeCount)
6028 return false;
6029 if (!data.length || !this.ranges)
6030 return this.getRange().isEqual(data);
6031
6032 for (var i = this.ranges.length; i--; ) {
6033 if (!this.ranges[i].isEqual(data[i]))
6034 return false;
6035 }
6036 return true;
6037 };
6038
6039 }).call(Selection.prototype);
6040
6041 exports.Selection = Selection;
6042 });
6043
6044 define("ace/tokenizer",["require","exports","module","ace/config"], function(require, exports, module) {
6045 "use strict";
6046
6047 var config = require("./config");
6048 var MAX_TOKEN_COUNT = 2000;
6049 var Tokenizer = function(rules) {
6050 this.states = rules;
6051
6052 this.regExps = {};
6053 this.matchMappings = {};
6054 for (var key in this.states) {
6055 var state = this.states[key];
6056 var ruleRegExps = [];
6057 var matchTotal = 0;
6058 var mapping = this.matchMappings[key] = {defaultToken: "text"};
6059 var flag = "g";
6060
6061 var splitterRurles = [];
6062 for (var i = 0; i < state.length; i++) {
6063 var rule = state[i];
6064 if (rule.defaultToken)
6065 mapping.defaultToken = rule.defaultToken;
6066 if (rule.caseInsensitive)
6067 flag = "gi";
6068 if (rule.regex == null)
6069 continue;
6070
6071 if (rule.regex instanceof RegExp)
6072 rule.regex = rule.regex.toString().slice(1, -1);
6073 var adjustedregex = rule.regex;
6074 var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
6075 if (Array.isArray(rule.token)) {
6076 if (rule.token.length == 1 || matchcount == 1) {
6077 rule.token = rule.token[0];
6078 } else if (matchcount - 1 != rule.token.length) {
6079 this.reportError("number of classes and regexp groups doesn't match", {
6080 rule: rule,
6081 groupCount: matchcount - 1
6082 });
6083 rule.token = rule.token[0];
6084 } else {
6085 rule.tokenArray = rule.token;
6086 rule.token = null;
6087 rule.onMatch = this.$arrayTokens;
6088 }
6089 } else if (typeof rule.token == "function" && !rule.onMatch) {
6090 if (matchcount > 1)
6091 rule.onMatch = this.$applyToken;
6092 else
6093 rule.onMatch = rule.token;
6094 }
6095
6096 if (matchcount > 1) {
6097 if (/\\\d/.test(rule.regex)) {
6098 adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) {
6099 return "\\" + (parseInt(digit, 10) + matchTotal + 1);
6100 });
6101 } else {
6102 matchcount = 1;
6103 adjustedregex = this.removeCapturingGroups(rule.regex);
6104 }
6105 if (!rule.splitRegex && typeof rule.token != "string")
6106 splitterRurles.push(rule); // flag will be known only at the very end
6107 }
6108
6109 mapping[matchTotal] = i;
6110 matchTotal += matchcount;
6111
6112 ruleRegExps.push(adjustedregex);
6113 if (!rule.onMatch)
6114 rule.onMatch = null;
6115 }
6116
6117 if (!ruleRegExps.length) {
6118 mapping[0] = 0;
6119 ruleRegExps.push("$");
6120 }
6121
6122 splitterRurles.forEach(function(rule) {
6123 rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
6124 }, this);
6125
6126 this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
6127 }
6128 };
6129
6130 (function() {
6131 this.$setMaxTokenCount = function(m) {
6132 MAX_TOKEN_COUNT = m | 0;
6133 };
6134
6135 this.$applyToken = function(str) {
6136 var values = this.splitRegex.exec(str).slice(1);
6137 var types = this.token.apply(this, values);
6138 if (typeof types === "string")
6139 return [{type: types, value: str}];
6140
6141 var tokens = [];
6142 for (var i = 0, l = types.length; i < l; i++) {
6143 if (values[i])
6144 tokens[tokens.length] = {
6145 type: types[i],
6146 value: values[i]
6147 };
6148 }
6149 return tokens;
6150 };
6151
6152 this.$arrayTokens = function(str) {
6153 if (!str)
6154 return [];
6155 var values = this.splitRegex.exec(str);
6156 if (!values)
6157 return "text";
6158 var tokens = [];
6159 var types = this.tokenArray;
6160 for (var i = 0, l = types.length; i < l; i++) {
6161 if (values[i + 1])
6162 tokens[tokens.length] = {
6163 type: types[i],
6164 value: values[i + 1]
6165 };
6166 }
6167 return tokens;
6168 };
6169
6170 this.removeCapturingGroups = function(src) {
6171 var r = src.replace(
6172 /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
6173 function(x, y) {return y ? "(?:" : x;}
6174 );
6175 return r;
6176 };
6177
6178 this.createSplitterRegexp = function(src, flag) {
6179 if (src.indexOf("(?=") != -1) {
6180 var stack = 0;
6181 var inChClass = false;
6182 var lastCapture = {};
6183 src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function(
6184 m, esc, parenOpen, parenClose, square, index
6185 ) {
6186 if (inChClass) {
6187 inChClass = square != "]";
6188 } else if (square) {
6189 inChClass = true;
6190 } else if (parenClose) {
6191 if (stack == lastCapture.stack) {
6192 lastCapture.end = index+1;
6193 lastCapture.stack = -1;
6194 }
6195 stack--;
6196 } else if (parenOpen) {
6197 stack++;
6198 if (parenOpen.length != 1) {
6199 lastCapture.stack = stack;
6200 lastCapture.start = index;
6201 }
6202 }
6203 return m;
6204 });
6205
6206 if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
6207 src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
6208 }
6209 if (src.charAt(0) != "^") src = "^" + src;
6210 if (src.charAt(src.length - 1) != "$") src += "$";
6211
6212 return new RegExp(src, (flag||"").replace("g", ""));
6213 };
6214 this.getLineTokens = function(line, startState) {
6215 if (startState && typeof startState != "string") {
6216 var stack = startState.slice(0);
6217 startState = stack[0];
6218 if (startState === "#tmp") {
6219 stack.shift();
6220 startState = stack.shift();
6221 }
6222 } else
6223 var stack = [];
6224
6225 var currentState = startState || "start";
6226 var state = this.states[currentState];
6227 if (!state) {
6228 currentState = "start";
6229 state = this.states[currentState];
6230 }
6231 var mapping = this.matchMappings[currentState];
6232 var re = this.regExps[currentState];
6233 re.lastIndex = 0;
6234
6235 var match, tokens = [];
6236 var lastIndex = 0;
6237 var matchAttempts = 0;
6238
6239 var token = {type: null, value: ""};
6240
6241 while (match = re.exec(line)) {
6242 var type = mapping.defaultToken;
6243 var rule = null;
6244 var value = match[0];
6245 var index = re.lastIndex;
6246
6247 if (index - value.length > lastIndex) {
6248 var skipped = line.substring(lastIndex, index - value.length);
6249 if (token.type == type) {
6250 token.value += skipped;
6251 } else {
6252 if (token.type)
6253 tokens.push(token);
6254 token = {type: type, value: skipped};
6255 }
6256 }
6257
6258 for (var i = 0; i < match.length-2; i++) {
6259 if (match[i + 1] === undefined)
6260 continue;
6261
6262 rule = state[mapping[i]];
6263
6264 if (rule.onMatch)
6265 type = rule.onMatch(value, currentState, stack, line);
6266 else
6267 type = rule.token;
6268
6269 if (rule.next) {
6270 if (typeof rule.next == "string") {
6271 currentState = rule.next;
6272 } else {
6273 currentState = rule.next(currentState, stack);
6274 }
6275
6276 state = this.states[currentState];
6277 if (!state) {
6278 this.reportError("state doesn't exist", currentState);
6279 currentState = "start";
6280 state = this.states[currentState];
6281 }
6282 mapping = this.matchMappings[currentState];
6283 lastIndex = index;
6284 re = this.regExps[currentState];
6285 re.lastIndex = index;
6286 }
6287 if (rule.consumeLineEnd)
6288 lastIndex = index;
6289 break;
6290 }
6291
6292 if (value) {
6293 if (typeof type === "string") {
6294 if ((!rule || rule.merge !== false) && token.type === type) {
6295 token.value += value;
6296 } else {
6297 if (token.type)
6298 tokens.push(token);
6299 token = {type: type, value: value};
6300 }
6301 } else if (type) {
6302 if (token.type)
6303 tokens.push(token);
6304 token = {type: null, value: ""};
6305 for (var i = 0; i < type.length; i++)
6306 tokens.push(type[i]);
6307 }
6308 }
6309
6310 if (lastIndex == line.length)
6311 break;
6312
6313 lastIndex = index;
6314
6315 if (matchAttempts++ > MAX_TOKEN_COUNT) {
6316 if (matchAttempts > 2 * line.length) {
6317 this.reportError("infinite loop with in ace tokenizer", {
6318 startState: startState,
6319 line: line
6320 });
6321 }
6322 while (lastIndex < line.length) {
6323 if (token.type)
6324 tokens.push(token);
6325 token = {
6326 value: line.substring(lastIndex, lastIndex += 2000),
6327 type: "overflow"
6328 };
6329 }
6330 currentState = "start";
6331 stack = [];
6332 break;
6333 }
6334 }
6335
6336 if (token.type)
6337 tokens.push(token);
6338
6339 if (stack.length > 1) {
6340 if (stack[0] !== currentState)
6341 stack.unshift("#tmp", currentState);
6342 }
6343 return {
6344 tokens : tokens,
6345 state : stack.length ? stack : currentState
6346 };
6347 };
6348
6349 this.reportError = config.reportError;
6350
6351 }).call(Tokenizer.prototype);
6352
6353 exports.Tokenizer = Tokenizer;
6354 });
6355
6356 define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"], function(require, exports, module) {
6357 "use strict";
6358
6359 var lang = require("../lib/lang");
6360
6361 var TextHighlightRules = function() {
6362
6363 this.$rules = {
6364 "start" : [{
6365 token : "empty_line",
6366 regex : '^$'
6367 }, {
6368 defaultToken : "text"
6369 }]
6370 };
6371 };
6372
6373 (function() {
6374
6375 this.addRules = function(rules, prefix) {
6376 if (!prefix) {
6377 for (var key in rules)
6378 this.$rules[key] = rules[key];
6379 return;
6380 }
6381 for (var key in rules) {
6382 var state = rules[key];
6383 for (var i = 0; i < state.length; i++) {
6384 var rule = state[i];
6385 if (rule.next || rule.onMatch) {
6386 if (typeof rule.next == "string") {
6387 if (rule.next.indexOf(prefix) !== 0)
6388 rule.next = prefix + rule.next;
6389 }
6390 if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)
6391 rule.nextState = prefix + rule.nextState;
6392 }
6393 }
6394 this.$rules[prefix + key] = state;
6395 }
6396 };
6397
6398 this.getRules = function() {
6399 return this.$rules;
6400 };
6401
6402 this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
6403 var embedRules = typeof HighlightRules == "function"
6404 ? new HighlightRules().getRules()
6405 : HighlightRules;
6406 if (states) {
6407 for (var i = 0; i < states.length; i++)
6408 states[i] = prefix + states[i];
6409 } else {
6410 states = [];
6411 for (var key in embedRules)
6412 states.push(prefix + key);
6413 }
6414
6415 this.addRules(embedRules, prefix);
6416
6417 if (escapeRules) {
6418 var addRules = Array.prototype[append ? "push" : "unshift"];
6419 for (var i = 0; i < states.length; i++)
6420 addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
6421 }
6422
6423 if (!this.$embeds)
6424 this.$embeds = [];
6425 this.$embeds.push(prefix);
6426 };
6427
6428 this.getEmbeds = function() {
6429 return this.$embeds;
6430 };
6431
6432 var pushState = function(currentState, stack) {
6433 if (currentState != "start" || stack.length)
6434 stack.unshift(this.nextState, currentState);
6435 return this.nextState;
6436 };
6437 var popState = function(currentState, stack) {
6438 stack.shift();
6439 return stack.shift() || "start";
6440 };
6441
6442 this.normalizeRules = function() {
6443 var id = 0;
6444 var rules = this.$rules;
6445 function processState(key) {
6446 var state = rules[key];
6447 state.processed = true;
6448 for (var i = 0; i < state.length; i++) {
6449 var rule = state[i];
6450 var toInsert = null;
6451 if (Array.isArray(rule)) {
6452 toInsert = rule;
6453 rule = {};
6454 }
6455 if (!rule.regex && rule.start) {
6456 rule.regex = rule.start;
6457 if (!rule.next)
6458 rule.next = [];
6459 rule.next.push({
6460 defaultToken: rule.token
6461 }, {
6462 token: rule.token + ".end",
6463 regex: rule.end || rule.start,
6464 next: "pop"
6465 });
6466 rule.token = rule.token + ".start";
6467 rule.push = true;
6468 }
6469 var next = rule.next || rule.push;
6470 if (next && Array.isArray(next)) {
6471 var stateName = rule.stateName;
6472 if (!stateName) {
6473 stateName = rule.token;
6474 if (typeof stateName != "string")
6475 stateName = stateName[0] || "";
6476 if (rules[stateName])
6477 stateName += id++;
6478 }
6479 rules[stateName] = next;
6480 rule.next = stateName;
6481 processState(stateName);
6482 } else if (next == "pop") {
6483 rule.next = popState;
6484 }
6485
6486 if (rule.push) {
6487 rule.nextState = rule.next || rule.push;
6488 rule.next = pushState;
6489 delete rule.push;
6490 }
6491
6492 if (rule.rules) {
6493 for (var r in rule.rules) {
6494 if (rules[r]) {
6495 if (rules[r].push)
6496 rules[r].push.apply(rules[r], rule.rules[r]);
6497 } else {
6498 rules[r] = rule.rules[r];
6499 }
6500 }
6501 }
6502 var includeName = typeof rule == "string" ? rule : rule.include;
6503 if (includeName) {
6504 if (Array.isArray(includeName))
6505 toInsert = includeName.map(function(x) { return rules[x]; });
6506 else
6507 toInsert = rules[includeName];
6508 }
6509
6510 if (toInsert) {
6511 var args = [i, 1].concat(toInsert);
6512 if (rule.noEscape)
6513 args = args.filter(function(x) {return !x.next;});
6514 state.splice.apply(state, args);
6515 i--;
6516 }
6517
6518 if (rule.keywordMap) {
6519 rule.token = this.createKeywordMapper(
6520 rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive
6521 );
6522 delete rule.defaultToken;
6523 }
6524 }
6525 }
6526 Object.keys(rules).forEach(processState, this);
6527 };
6528
6529 this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
6530 var keywords = Object.create(null);
6531 Object.keys(map).forEach(function(className) {
6532 var a = map[className];
6533 if (ignoreCase)
6534 a = a.toLowerCase();
6535 var list = a.split(splitChar || "|");
6536 for (var i = list.length; i--; )
6537 keywords[list[i]] = className;
6538 });
6539 if (Object.getPrototypeOf(keywords)) {
6540 keywords.__proto__ = null;
6541 }
6542 this.$keywordList = Object.keys(keywords);
6543 map = null;
6544 return ignoreCase
6545 ? function(value) {return keywords[value.toLowerCase()] || defaultToken; }
6546 : function(value) {return keywords[value] || defaultToken; };
6547 };
6548
6549 this.getKeywords = function() {
6550 return this.$keywords;
6551 };
6552
6553 }).call(TextHighlightRules.prototype);
6554
6555 exports.TextHighlightRules = TextHighlightRules;
6556 });
6557
6558 define("ace/mode/behaviour",["require","exports","module"], function(require, exports, module) {
6559 "use strict";
6560
6561 var Behaviour = function() {
6562 this.$behaviours = {};
6563 };
6564
6565 (function () {
6566
6567 this.add = function (name, action, callback) {
6568 switch (undefined) {
6569 case this.$behaviours:
6570 this.$behaviours = {};
6571 case this.$behaviours[name]:
6572 this.$behaviours[name] = {};
6573 }
6574 this.$behaviours[name][action] = callback;
6575 };
6576
6577 this.addBehaviours = function (behaviours) {
6578 for (var key in behaviours) {
6579 for (var action in behaviours[key]) {
6580 this.add(key, action, behaviours[key][action]);
6581 }
6582 }
6583 };
6584
6585 this.remove = function (name) {
6586 if (this.$behaviours && this.$behaviours[name]) {
6587 delete this.$behaviours[name];
6588 }
6589 };
6590
6591 this.inherit = function (mode, filter) {
6592 if (typeof mode === "function") {
6593 var behaviours = new mode().getBehaviours(filter);
6594 } else {
6595 var behaviours = mode.getBehaviours(filter);
6596 }
6597 this.addBehaviours(behaviours);
6598 };
6599
6600 this.getBehaviours = function (filter) {
6601 if (!filter) {
6602 return this.$behaviours;
6603 } else {
6604 var ret = {};
6605 for (var i = 0; i < filter.length; i++) {
6606 if (this.$behaviours[filter[i]]) {
6607 ret[filter[i]] = this.$behaviours[filter[i]];
6608 }
6609 }
6610 return ret;
6611 }
6612 };
6613
6614 }).call(Behaviour.prototype);
6615
6616 exports.Behaviour = Behaviour;
6617 });
6618
6619 define("ace/token_iterator",["require","exports","module","ace/range"], function(require, exports, module) {
6620 "use strict";
6621
6622 var Range = require("./range").Range;
6623 var TokenIterator = function(session, initialRow, initialColumn) {
6624 this.$session = session;
6625 this.$row = initialRow;
6626 this.$rowTokens = session.getTokens(initialRow);
6627
6628 var token = session.getTokenAt(initialRow, initialColumn);
6629 this.$tokenIndex = token ? token.index : -1;
6630 };
6631
6632 (function() {
6633 this.stepBackward = function() {
6634 this.$tokenIndex -= 1;
6635
6636 while (this.$tokenIndex < 0) {
6637 this.$row -= 1;
6638 if (this.$row < 0) {
6639 this.$row = 0;
6640 return null;
6641 }
6642
6643 this.$rowTokens = this.$session.getTokens(this.$row);
6644 this.$tokenIndex = this.$rowTokens.length - 1;
6645 }
6646
6647 return this.$rowTokens[this.$tokenIndex];
6648 };
6649 this.stepForward = function() {
6650 this.$tokenIndex += 1;
6651 var rowCount;
6652 while (this.$tokenIndex >= this.$rowTokens.length) {
6653 this.$row += 1;
6654 if (!rowCount)
6655 rowCount = this.$session.getLength();
6656 if (this.$row >= rowCount) {
6657 this.$row = rowCount - 1;
6658 return null;
6659 }
6660
6661 this.$rowTokens = this.$session.getTokens(this.$row);
6662 this.$tokenIndex = 0;
6663 }
6664
6665 return this.$rowTokens[this.$tokenIndex];
6666 };
6667 this.getCurrentToken = function () {
6668 return this.$rowTokens[this.$tokenIndex];
6669 };
6670 this.getCurrentTokenRow = function () {
6671 return this.$row;
6672 };
6673 this.getCurrentTokenColumn = function() {
6674 var rowTokens = this.$rowTokens;
6675 var tokenIndex = this.$tokenIndex;
6676 var column = rowTokens[tokenIndex].start;
6677 if (column !== undefined)
6678 return column;
6679
6680 column = 0;
6681 while (tokenIndex > 0) {
6682 tokenIndex -= 1;
6683 column += rowTokens[tokenIndex].value.length;
6684 }
6685
6686 return column;
6687 };
6688 this.getCurrentTokenPosition = function() {
6689 return {row: this.$row, column: this.getCurrentTokenColumn()};
6690 };
6691 this.getCurrentTokenRange = function() {
6692 var token = this.$rowTokens[this.$tokenIndex];
6693 var column = this.getCurrentTokenColumn();
6694 return new Range(this.$row, column, this.$row, column + token.value.length);
6695 };
6696
6697 }).call(TokenIterator.prototype);
6698
6699 exports.TokenIterator = TokenIterator;
6700 });
6701
6702 define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
6703 "use strict";
6704
6705 var oop = require("../../lib/oop");
6706 var Behaviour = require("../behaviour").Behaviour;
6707 var TokenIterator = require("../../token_iterator").TokenIterator;
6708 var lang = require("../../lib/lang");
6709
6710 var SAFE_INSERT_IN_TOKENS =
6711 ["text", "paren.rparen", "punctuation.operator"];
6712 var SAFE_INSERT_BEFORE_TOKENS =
6713 ["text", "paren.rparen", "punctuation.operator", "comment"];
6714
6715 var context;
6716 var contextCache = {};
6717 var defaultQuotes = {'"' : '"', "'" : "'"};
6718
6719 var initContext = function(editor) {
6720 var id = -1;
6721 if (editor.multiSelect) {
6722 id = editor.selection.index;
6723 if (contextCache.rangeCount != editor.multiSelect.rangeCount)
6724 contextCache = {rangeCount: editor.multiSelect.rangeCount};
6725 }
6726 if (contextCache[id])
6727 return context = contextCache[id];
6728 context = contextCache[id] = {
6729 autoInsertedBrackets: 0,
6730 autoInsertedRow: -1,
6731 autoInsertedLineEnd: "",
6732 maybeInsertedBrackets: 0,
6733 maybeInsertedRow: -1,
6734 maybeInsertedLineStart: "",
6735 maybeInsertedLineEnd: ""
6736 };
6737 };
6738
6739 var getWrapped = function(selection, selected, opening, closing) {
6740 var rowDiff = selection.end.row - selection.start.row;
6741 return {
6742 text: opening + selected + closing,
6743 selection: [
6744 0,
6745 selection.start.column + 1,
6746 rowDiff,
6747 selection.end.column + (rowDiff ? 0 : 1)
6748 ]
6749 };
6750 };
6751
6752 var CstyleBehaviour = function(options) {
6753 this.add("braces", "insertion", function(state, action, editor, session, text) {
6754 var cursor = editor.getCursorPosition();
6755 var line = session.doc.getLine(cursor.row);
6756 if (text == '{') {
6757 initContext(editor);
6758 var selection = editor.getSelectionRange();
6759 var selected = session.doc.getTextRange(selection);
6760 if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
6761 return getWrapped(selection, selected, '{', '}');
6762 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6763 if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) {
6764 CstyleBehaviour.recordAutoInsert(editor, session, "}");
6765 return {
6766 text: '{}',
6767 selection: [1, 1]
6768 };
6769 } else {
6770 CstyleBehaviour.recordMaybeInsert(editor, session, "{");
6771 return {
6772 text: '{',
6773 selection: [1, 1]
6774 };
6775 }
6776 }
6777 } else if (text == '}') {
6778 initContext(editor);
6779 var rightChar = line.substring(cursor.column, cursor.column + 1);
6780 if (rightChar == '}') {
6781 var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
6782 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6783 CstyleBehaviour.popAutoInsertedClosing();
6784 return {
6785 text: '',
6786 selection: [1, 1]
6787 };
6788 }
6789 }
6790 } else if (text == "\n" || text == "\r\n") {
6791 initContext(editor);
6792 var closing = "";
6793 if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
6794 closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
6795 CstyleBehaviour.clearMaybeInsertedClosing();
6796 }
6797 var rightChar = line.substring(cursor.column, cursor.column + 1);
6798 if (rightChar === '}') {
6799 var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
6800 if (!openBracePos)
6801 return null;
6802 var next_indent = this.$getIndent(session.getLine(openBracePos.row));
6803 } else if (closing) {
6804 var next_indent = this.$getIndent(line);
6805 } else {
6806 CstyleBehaviour.clearMaybeInsertedClosing();
6807 return;
6808 }
6809 var indent = next_indent + session.getTabString();
6810
6811 return {
6812 text: '\n' + indent + '\n' + next_indent + closing,
6813 selection: [1, indent.length, 1, indent.length]
6814 };
6815 } else {
6816 CstyleBehaviour.clearMaybeInsertedClosing();
6817 }
6818 });
6819
6820 this.add("braces", "deletion", function(state, action, editor, session, range) {
6821 var selected = session.doc.getTextRange(range);
6822 if (!range.isMultiLine() && selected == '{') {
6823 initContext(editor);
6824 var line = session.doc.getLine(range.start.row);
6825 var rightChar = line.substring(range.end.column, range.end.column + 1);
6826 if (rightChar == '}') {
6827 range.end.column++;
6828 return range;
6829 } else {
6830 context.maybeInsertedBrackets--;
6831 }
6832 }
6833 });
6834
6835 this.add("parens", "insertion", function(state, action, editor, session, text) {
6836 if (text == '(') {
6837 initContext(editor);
6838 var selection = editor.getSelectionRange();
6839 var selected = session.doc.getTextRange(selection);
6840 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
6841 return getWrapped(selection, selected, '(', ')');
6842 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6843 CstyleBehaviour.recordAutoInsert(editor, session, ")");
6844 return {
6845 text: '()',
6846 selection: [1, 1]
6847 };
6848 }
6849 } else if (text == ')') {
6850 initContext(editor);
6851 var cursor = editor.getCursorPosition();
6852 var line = session.doc.getLine(cursor.row);
6853 var rightChar = line.substring(cursor.column, cursor.column + 1);
6854 if (rightChar == ')') {
6855 var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
6856 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6857 CstyleBehaviour.popAutoInsertedClosing();
6858 return {
6859 text: '',
6860 selection: [1, 1]
6861 };
6862 }
6863 }
6864 }
6865 });
6866
6867 this.add("parens", "deletion", function(state, action, editor, session, range) {
6868 var selected = session.doc.getTextRange(range);
6869 if (!range.isMultiLine() && selected == '(') {
6870 initContext(editor);
6871 var line = session.doc.getLine(range.start.row);
6872 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6873 if (rightChar == ')') {
6874 range.end.column++;
6875 return range;
6876 }
6877 }
6878 });
6879
6880 this.add("brackets", "insertion", function(state, action, editor, session, text) {
6881 if (text == '[') {
6882 initContext(editor);
6883 var selection = editor.getSelectionRange();
6884 var selected = session.doc.getTextRange(selection);
6885 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
6886 return getWrapped(selection, selected, '[', ']');
6887 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
6888 CstyleBehaviour.recordAutoInsert(editor, session, "]");
6889 return {
6890 text: '[]',
6891 selection: [1, 1]
6892 };
6893 }
6894 } else if (text == ']') {
6895 initContext(editor);
6896 var cursor = editor.getCursorPosition();
6897 var line = session.doc.getLine(cursor.row);
6898 var rightChar = line.substring(cursor.column, cursor.column + 1);
6899 if (rightChar == ']') {
6900 var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
6901 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
6902 CstyleBehaviour.popAutoInsertedClosing();
6903 return {
6904 text: '',
6905 selection: [1, 1]
6906 };
6907 }
6908 }
6909 }
6910 });
6911
6912 this.add("brackets", "deletion", function(state, action, editor, session, range) {
6913 var selected = session.doc.getTextRange(range);
6914 if (!range.isMultiLine() && selected == '[') {
6915 initContext(editor);
6916 var line = session.doc.getLine(range.start.row);
6917 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6918 if (rightChar == ']') {
6919 range.end.column++;
6920 return range;
6921 }
6922 }
6923 });
6924
6925 this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
6926 var quotes = session.$mode.$quotes || defaultQuotes;
6927 if (text.length == 1 && quotes[text]) {
6928 if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1)
6929 return;
6930 initContext(editor);
6931 var quote = text;
6932 var selection = editor.getSelectionRange();
6933 var selected = session.doc.getTextRange(selection);
6934 if (selected !== "" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) {
6935 return getWrapped(selection, selected, quote, quote);
6936 } else if (!selected) {
6937 var cursor = editor.getCursorPosition();
6938 var line = session.doc.getLine(cursor.row);
6939 var leftChar = line.substring(cursor.column-1, cursor.column);
6940 var rightChar = line.substring(cursor.column, cursor.column + 1);
6941
6942 var token = session.getTokenAt(cursor.row, cursor.column);
6943 var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);
6944 if (leftChar == "\\" && token && /escape/.test(token.type))
6945 return null;
6946
6947 var stringBefore = token && /string|escape/.test(token.type);
6948 var stringAfter = !rightToken || /string|escape/.test(rightToken.type);
6949
6950 var pair;
6951 if (rightChar == quote) {
6952 pair = stringBefore !== stringAfter;
6953 if (pair && /string\.end/.test(rightToken.type))
6954 pair = false;
6955 } else {
6956 if (stringBefore && !stringAfter)
6957 return null; // wrap string with different quote
6958 if (stringBefore && stringAfter)
6959 return null; // do not pair quotes inside strings
6960 var wordRe = session.$mode.tokenRe;
6961 wordRe.lastIndex = 0;
6962 var isWordBefore = wordRe.test(leftChar);
6963 wordRe.lastIndex = 0;
6964 var isWordAfter = wordRe.test(leftChar);
6965 if (isWordBefore || isWordAfter)
6966 return null; // before or after alphanumeric
6967 if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
6968 return null; // there is rightChar and it isn't closing
6969 pair = true;
6970 }
6971 return {
6972 text: pair ? quote + quote : "",
6973 selection: [1,1]
6974 };
6975 }
6976 }
6977 });
6978
6979 this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
6980 var selected = session.doc.getTextRange(range);
6981 if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
6982 initContext(editor);
6983 var line = session.doc.getLine(range.start.row);
6984 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
6985 if (rightChar == selected) {
6986 range.end.column++;
6987 return range;
6988 }
6989 }
6990 });
6991
6992 };
6993
6994
6995 CstyleBehaviour.isSaneInsertion = function(editor, session) {
6996 var cursor = editor.getCursorPosition();
6997 var iterator = new TokenIterator(session, cursor.row, cursor.column);
6998 if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
6999 var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
7000 if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
7001 return false;
7002 }
7003 iterator.stepForward();
7004 return iterator.getCurrentTokenRow() !== cursor.row ||
7005 this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
7006 };
7007
7008 CstyleBehaviour.$matchTokenType = function(token, types) {
7009 return types.indexOf(token.type || token) > -1;
7010 };
7011
7012 CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
7013 var cursor = editor.getCursorPosition();
7014 var line = session.doc.getLine(cursor.row);
7015 if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
7016 context.autoInsertedBrackets = 0;
7017 context.autoInsertedRow = cursor.row;
7018 context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
7019 context.autoInsertedBrackets++;
7020 };
7021
7022 CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
7023 var cursor = editor.getCursorPosition();
7024 var line = session.doc.getLine(cursor.row);
7025 if (!this.isMaybeInsertedClosing(cursor, line))
7026 context.maybeInsertedBrackets = 0;
7027 context.maybeInsertedRow = cursor.row;
7028 context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
7029 context.maybeInsertedLineEnd = line.substr(cursor.column);
7030 context.maybeInsertedBrackets++;
7031 };
7032
7033 CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
7034 return context.autoInsertedBrackets > 0 &&
7035 cursor.row === context.autoInsertedRow &&
7036 bracket === context.autoInsertedLineEnd[0] &&
7037 line.substr(cursor.column) === context.autoInsertedLineEnd;
7038 };
7039
7040 CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
7041 return context.maybeInsertedBrackets > 0 &&
7042 cursor.row === context.maybeInsertedRow &&
7043 line.substr(cursor.column) === context.maybeInsertedLineEnd &&
7044 line.substr(0, cursor.column) == context.maybeInsertedLineStart;
7045 };
7046
7047 CstyleBehaviour.popAutoInsertedClosing = function() {
7048 context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
7049 context.autoInsertedBrackets--;
7050 };
7051
7052 CstyleBehaviour.clearMaybeInsertedClosing = function() {
7053 if (context) {
7054 context.maybeInsertedBrackets = 0;
7055 context.maybeInsertedRow = -1;
7056 }
7057 };
7058
7059
7060
7061 oop.inherits(CstyleBehaviour, Behaviour);
7062
7063 exports.CstyleBehaviour = CstyleBehaviour;
7064 });
7065
7066 define("ace/unicode",["require","exports","module"], function(require, exports, module) {
7067 "use strict";
7068 exports.packages = {};
7069
7070 addUnicodePackage({
7071 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",
7072 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",
7073 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",
7074 Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",
7075 Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",
7076 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",
7077 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",
7078 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",
7079 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",
7080 Me: "0488048906DE20DD-20E020E2-20E4A670-A672",
7081 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",
7082 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",
7083 Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",
7084 No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",
7085 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",
7086 Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",
7087 Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",
7088 Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",
7089 Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",
7090 Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21",
7091 Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F",
7092 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",
7093 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",
7094 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",
7095 Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",
7096 Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",
7097 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",
7098 Z: "002000A01680180E2000-200A20282029202F205F3000",
7099 Zs: "002000A01680180E2000-200A202F205F3000",
7100 Zl: "2028",
7101 Zp: "2029",
7102 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",
7103 Cc: "0000-001F007F-009F",
7104 Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",
7105 Co: "E000-F8FF",
7106 Cs: "D800-DFFF",
7107 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"
7108 });
7109
7110 function addUnicodePackage (pack) {
7111 var codePoint = /\w{4}/g;
7112 for (var name in pack)
7113 exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
7114 }
7115
7116 });
7117
7118 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(require, exports, module) {
7119 "use strict";
7120
7121 var Tokenizer = require("../tokenizer").Tokenizer;
7122 var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
7123 var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
7124 var unicode = require("../unicode");
7125 var lang = require("../lib/lang");
7126 var TokenIterator = require("../token_iterator").TokenIterator;
7127 var Range = require("../range").Range;
7128
7129 var Mode = function() {
7130 this.HighlightRules = TextHighlightRules;
7131 };
7132
7133 (function() {
7134 this.$defaultBehaviour = new CstyleBehaviour();
7135
7136 this.tokenRe = new RegExp("^["
7137 + unicode.packages.L
7138 + unicode.packages.Mn + unicode.packages.Mc
7139 + unicode.packages.Nd
7140 + unicode.packages.Pc + "\\$_]+", "g"
7141 );
7142
7143 this.nonTokenRe = new RegExp("^(?:[^"
7144 + unicode.packages.L
7145 + unicode.packages.Mn + unicode.packages.Mc
7146 + unicode.packages.Nd
7147 + unicode.packages.Pc + "\\$_]|\\s])+", "g"
7148 );
7149
7150 this.getTokenizer = function() {
7151 if (!this.$tokenizer) {
7152 this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig);
7153 this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());
7154 }
7155 return this.$tokenizer;
7156 };
7157
7158 this.lineCommentStart = "";
7159 this.blockComment = "";
7160
7161 this.toggleCommentLines = function(state, session, startRow, endRow) {
7162 var doc = session.doc;
7163
7164 var ignoreBlankLines = true;
7165 var shouldRemove = true;
7166 var minIndent = Infinity;
7167 var tabSize = session.getTabSize();
7168 var insertAtTabStop = false;
7169
7170 if (!this.lineCommentStart) {
7171 if (!this.blockComment)
7172 return false;
7173 var lineCommentStart = this.blockComment.start;
7174 var lineCommentEnd = this.blockComment.end;
7175 var regexpStart = new RegExp("^(\\s*)(?:" + lang.escapeRegExp(lineCommentStart) + ")");
7176 var regexpEnd = new RegExp("(?:" + lang.escapeRegExp(lineCommentEnd) + ")\\s*$");
7177
7178 var comment = function(line, i) {
7179 if (testRemove(line, i))
7180 return;
7181 if (!ignoreBlankLines || /\S/.test(line)) {
7182 doc.insertInLine({row: i, column: line.length}, lineCommentEnd);
7183 doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
7184 }
7185 };
7186
7187 var uncomment = function(line, i) {
7188 var m;
7189 if (m = line.match(regexpEnd))
7190 doc.removeInLine(i, line.length - m[0].length, line.length);
7191 if (m = line.match(regexpStart))
7192 doc.removeInLine(i, m[1].length, m[0].length);
7193 };
7194
7195 var testRemove = function(line, row) {
7196 if (regexpStart.test(line))
7197 return true;
7198 var tokens = session.getTokens(row);
7199 for (var i = 0; i < tokens.length; i++) {
7200 if (tokens[i].type === "comment")
7201 return true;
7202 }
7203 };
7204 } else {
7205 if (Array.isArray(this.lineCommentStart)) {
7206 var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|");
7207 var lineCommentStart = this.lineCommentStart[0];
7208 } else {
7209 var regexpStart = lang.escapeRegExp(this.lineCommentStart);
7210 var lineCommentStart = this.lineCommentStart;
7211 }
7212 regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?");
7213
7214 insertAtTabStop = session.getUseSoftTabs();
7215
7216 var uncomment = function(line, i) {
7217 var m = line.match(regexpStart);
7218 if (!m) return;
7219 var start = m[1].length, end = m[0].length;
7220 if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ")
7221 end--;
7222 doc.removeInLine(i, start, end);
7223 };
7224 var commentWithSpace = lineCommentStart + " ";
7225 var comment = function(line, i) {
7226 if (!ignoreBlankLines || /\S/.test(line)) {
7227 if (shouldInsertSpace(line, minIndent, minIndent))
7228 doc.insertInLine({row: i, column: minIndent}, commentWithSpace);
7229 else
7230 doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
7231 }
7232 };
7233 var testRemove = function(line, i) {
7234 return regexpStart.test(line);
7235 };
7236
7237 var shouldInsertSpace = function(line, before, after) {
7238 var spaces = 0;
7239 while (before-- && line.charAt(before) == " ")
7240 spaces++;
7241 if (spaces % tabSize != 0)
7242 return false;
7243 var spaces = 0;
7244 while (line.charAt(after++) == " ")
7245 spaces++;
7246 if (tabSize > 2)
7247 return spaces % tabSize != tabSize - 1;
7248 else
7249 return spaces % tabSize == 0;
7250 return true;
7251 };
7252 }
7253
7254 function iter(fun) {
7255 for (var i = startRow; i <= endRow; i++)
7256 fun(doc.getLine(i), i);
7257 }
7258
7259
7260 var minEmptyLength = Infinity;
7261 iter(function(line, i) {
7262 var indent = line.search(/\S/);
7263 if (indent !== -1) {
7264 if (indent < minIndent)
7265 minIndent = indent;
7266 if (shouldRemove && !testRemove(line, i))
7267 shouldRemove = false;
7268 } else if (minEmptyLength > line.length) {
7269 minEmptyLength = line.length;
7270 }
7271 });
7272
7273 if (minIndent == Infinity) {
7274 minIndent = minEmptyLength;
7275 ignoreBlankLines = false;
7276 shouldRemove = false;
7277 }
7278
7279 if (insertAtTabStop && minIndent % tabSize != 0)
7280 minIndent = Math.floor(minIndent / tabSize) * tabSize;
7281
7282 iter(shouldRemove ? uncomment : comment);
7283 };
7284
7285 this.toggleBlockComment = function(state, session, range, cursor) {
7286 var comment = this.blockComment;
7287 if (!comment)
7288 return;
7289 if (!comment.start && comment[0])
7290 comment = comment[0];
7291
7292 var iterator = new TokenIterator(session, cursor.row, cursor.column);
7293 var token = iterator.getCurrentToken();
7294
7295 var sel = session.selection;
7296 var initialRange = session.selection.toOrientedRange();
7297 var startRow, colDiff;
7298
7299 if (token && /comment/.test(token.type)) {
7300 var startRange, endRange;
7301 while (token && /comment/.test(token.type)) {
7302 var i = token.value.indexOf(comment.start);
7303 if (i != -1) {
7304 var row = iterator.getCurrentTokenRow();
7305 var column = iterator.getCurrentTokenColumn() + i;
7306 startRange = new Range(row, column, row, column + comment.start.length);
7307 break;
7308 }
7309 token = iterator.stepBackward();
7310 }
7311
7312 var iterator = new TokenIterator(session, cursor.row, cursor.column);
7313 var token = iterator.getCurrentToken();
7314 while (token && /comment/.test(token.type)) {
7315 var i = token.value.indexOf(comment.end);
7316 if (i != -1) {
7317 var row = iterator.getCurrentTokenRow();
7318 var column = iterator.getCurrentTokenColumn() + i;
7319 endRange = new Range(row, column, row, column + comment.end.length);
7320 break;
7321 }
7322 token = iterator.stepForward();
7323 }
7324 if (endRange)
7325 session.remove(endRange);
7326 if (startRange) {
7327 session.remove(startRange);
7328 startRow = startRange.start.row;
7329 colDiff = -comment.start.length;
7330 }
7331 } else {
7332 colDiff = comment.start.length;
7333 startRow = range.start.row;
7334 session.insert(range.end, comment.end);
7335 session.insert(range.start, comment.start);
7336 }
7337 if (initialRange.start.row == startRow)
7338 initialRange.start.column += colDiff;
7339 if (initialRange.end.row == startRow)
7340 initialRange.end.column += colDiff;
7341 session.selection.fromOrientedRange(initialRange);
7342 };
7343
7344 this.getNextLineIndent = function(state, line, tab) {
7345 return this.$getIndent(line);
7346 };
7347
7348 this.checkOutdent = function(state, line, input) {
7349 return false;
7350 };
7351
7352 this.autoOutdent = function(state, doc, row) {
7353 };
7354
7355 this.$getIndent = function(line) {
7356 return line.match(/^\s*/)[0];
7357 };
7358
7359 this.createWorker = function(session) {
7360 return null;
7361 };
7362
7363 this.createModeDelegates = function (mapping) {
7364 this.$embeds = [];
7365 this.$modes = {};
7366 for (var i in mapping) {
7367 if (mapping[i]) {
7368 this.$embeds.push(i);
7369 this.$modes[i] = new mapping[i]();
7370 }
7371 }
7372
7373 var delegations = ["toggleBlockComment", "toggleCommentLines", "getNextLineIndent",
7374 "checkOutdent", "autoOutdent", "transformAction", "getCompletions"];
7375
7376 for (var i = 0; i < delegations.length; i++) {
7377 (function(scope) {
7378 var functionName = delegations[i];
7379 var defaultHandler = scope[functionName];
7380 scope[delegations[i]] = function() {
7381 return this.$delegator(functionName, arguments, defaultHandler);
7382 };
7383 }(this));
7384 }
7385 };
7386
7387 this.$delegator = function(method, args, defaultHandler) {
7388 var state = args[0];
7389 if (typeof state != "string")
7390 state = state[0];
7391 for (var i = 0; i < this.$embeds.length; i++) {
7392 if (!this.$modes[this.$embeds[i]]) continue;
7393
7394 var split = state.split(this.$embeds[i]);
7395 if (!split[0] && split[1]) {
7396 args[0] = split[1];
7397 var mode = this.$modes[this.$embeds[i]];
7398 return mode[method].apply(mode, args);
7399 }
7400 }
7401 var ret = defaultHandler.apply(this, args);
7402 return defaultHandler ? ret : undefined;
7403 };
7404
7405 this.transformAction = function(state, action, editor, session, param) {
7406 if (this.$behaviour) {
7407 var behaviours = this.$behaviour.getBehaviours();
7408 for (var key in behaviours) {
7409 if (behaviours[key][action]) {
7410 var ret = behaviours[key][action].apply(this, arguments);
7411 if (ret) {
7412 return ret;
7413 }
7414 }
7415 }
7416 }
7417 };
7418
7419 this.getKeywords = function(append) {
7420 if (!this.completionKeywords) {
7421 var rules = this.$tokenizer.rules;
7422 var completionKeywords = [];
7423 for (var rule in rules) {
7424 var ruleItr = rules[rule];
7425 for (var r = 0, l = ruleItr.length; r < l; r++) {
7426 if (typeof ruleItr[r].token === "string") {
7427 if (/keyword|support|storage/.test(ruleItr[r].token))
7428 completionKeywords.push(ruleItr[r].regex);
7429 }
7430 else if (typeof ruleItr[r].token === "object") {
7431 for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {
7432 if (/keyword|support|storage/.test(ruleItr[r].token[a])) {
7433 var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a];
7434 completionKeywords.push(rule.substr(1, rule.length - 2));
7435 }
7436 }
7437 }
7438 }
7439 }
7440 this.completionKeywords = completionKeywords;
7441 }
7442 if (!append)
7443 return this.$keywordList;
7444 return completionKeywords.concat(this.$keywordList || []);
7445 };
7446
7447 this.$createKeywordList = function() {
7448 if (!this.$highlightRules)
7449 this.getTokenizer();
7450 return this.$keywordList = this.$highlightRules.$keywordList || [];
7451 };
7452
7453 this.getCompletions = function(state, session, pos, prefix) {
7454 var keywords = this.$keywordList || this.$createKeywordList();
7455 return keywords.map(function(word) {
7456 return {
7457 name: word,
7458 value: word,
7459 score: 0,
7460 meta: "keyword"
7461 };
7462 });
7463 };
7464
7465 this.$id = "ace/mode/text";
7466 }).call(Mode.prototype);
7467
7468 exports.Mode = Mode;
7469 });
7470
7471 define("ace/apply_delta",["require","exports","module"], function(require, exports, module) {
7472 "use strict";
7473
7474 function throwDeltaError(delta, errorText){
7475 console.log("Invalid Delta:", delta);
7476 throw "Invalid Delta: " + errorText;
7477 }
7478
7479 function positionInDocument(docLines, position) {
7480 return position.row >= 0 && position.row < docLines.length &&
7481 position.column >= 0 && position.column <= docLines[position.row].length;
7482 }
7483
7484 function validateDelta(docLines, delta) {
7485 if (delta.action != "insert" && delta.action != "remove")
7486 throwDeltaError(delta, "delta.action must be 'insert' or 'remove'");
7487 if (!(delta.lines instanceof Array))
7488 throwDeltaError(delta, "delta.lines must be an Array");
7489 if (!delta.start || !delta.end)
7490 throwDeltaError(delta, "delta.start/end must be an present");
7491 var start = delta.start;
7492 if (!positionInDocument(docLines, delta.start))
7493 throwDeltaError(delta, "delta.start must be contained in document");
7494 var end = delta.end;
7495 if (delta.action == "remove" && !positionInDocument(docLines, end))
7496 throwDeltaError(delta, "delta.end must contained in document for 'remove' actions");
7497 var numRangeRows = end.row - start.row;
7498 var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0));
7499 if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars)
7500 throwDeltaError(delta, "delta.range must match delta lines");
7501 }
7502
7503 exports.applyDelta = function(docLines, delta, doNotValidate) {
7504
7505 var row = delta.start.row;
7506 var startColumn = delta.start.column;
7507 var line = docLines[row] || "";
7508 switch (delta.action) {
7509 case "insert":
7510 var lines = delta.lines;
7511 if (lines.length === 1) {
7512 docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
7513 } else {
7514 var args = [row, 1].concat(delta.lines);
7515 docLines.splice.apply(docLines, args);
7516 docLines[row] = line.substring(0, startColumn) + docLines[row];
7517 docLines[row + delta.lines.length - 1] += line.substring(startColumn);
7518 }
7519 break;
7520 case "remove":
7521 var endColumn = delta.end.column;
7522 var endRow = delta.end.row;
7523 if (row === endRow) {
7524 docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);
7525 } else {
7526 docLines.splice(
7527 row, endRow - row + 1,
7528 line.substring(0, startColumn) + docLines[endRow].substring(endColumn)
7529 );
7530 }
7531 break;
7532 }
7533 };
7534 });
7535
7536 define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) {
7537 "use strict";
7538
7539 var oop = require("./lib/oop");
7540 var EventEmitter = require("./lib/event_emitter").EventEmitter;
7541
7542 var Anchor = exports.Anchor = function(doc, row, column) {
7543 this.$onChange = this.onChange.bind(this);
7544 this.attach(doc);
7545
7546 if (typeof column == "undefined")
7547 this.setPosition(row.row, row.column);
7548 else
7549 this.setPosition(row, column);
7550 };
7551
7552 (function() {
7553
7554 oop.implement(this, EventEmitter);
7555 this.getPosition = function() {
7556 return this.$clipPositionToDocument(this.row, this.column);
7557 };
7558 this.getDocument = function() {
7559 return this.document;
7560 };
7561 this.$insertRight = false;
7562 this.onChange = function(delta) {
7563 if (delta.start.row == delta.end.row && delta.start.row != this.row)
7564 return;
7565
7566 if (delta.start.row > this.row)
7567 return;
7568
7569 var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);
7570 this.setPosition(point.row, point.column, true);
7571 };
7572
7573 function $pointsInOrder(point1, point2, equalPointsInOrder) {
7574 var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;
7575 return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);
7576 }
7577
7578 function $getTransformedPoint(delta, point, moveIfEqual) {
7579 var deltaIsInsert = delta.action == "insert";
7580 var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row);
7581 var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);
7582 var deltaStart = delta.start;
7583 var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.
7584 if ($pointsInOrder(point, deltaStart, moveIfEqual)) {
7585 return {
7586 row: point.row,
7587 column: point.column
7588 };
7589 }
7590 if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {
7591 return {
7592 row: point.row + deltaRowShift,
7593 column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)
7594 };
7595 }
7596
7597 return {
7598 row: deltaStart.row,
7599 column: deltaStart.column
7600 };
7601 }
7602 this.setPosition = function(row, column, noClip) {
7603 var pos;
7604 if (noClip) {
7605 pos = {
7606 row: row,
7607 column: column
7608 };
7609 } else {
7610 pos = this.$clipPositionToDocument(row, column);
7611 }
7612
7613 if (this.row == pos.row && this.column == pos.column)
7614 return;
7615
7616 var old = {
7617 row: this.row,
7618 column: this.column
7619 };
7620
7621 this.row = pos.row;
7622 this.column = pos.column;
7623 this._signal("change", {
7624 old: old,
7625 value: pos
7626 });
7627 };
7628 this.detach = function() {
7629 this.document.removeEventListener("change", this.$onChange);
7630 };
7631 this.attach = function(doc) {
7632 this.document = doc || this.document;
7633 this.document.on("change", this.$onChange);
7634 };
7635 this.$clipPositionToDocument = function(row, column) {
7636 var pos = {};
7637
7638 if (row >= this.document.getLength()) {
7639 pos.row = Math.max(0, this.document.getLength() - 1);
7640 pos.column = this.document.getLine(pos.row).length;
7641 }
7642 else if (row < 0) {
7643 pos.row = 0;
7644 pos.column = 0;
7645 }
7646 else {
7647 pos.row = row;
7648 pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
7649 }
7650
7651 if (column < 0)
7652 pos.column = 0;
7653
7654 return pos;
7655 };
7656
7657 }).call(Anchor.prototype);
7658
7659 });
7660
7661 define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) {
7662 "use strict";
7663
7664 var oop = require("./lib/oop");
7665 var applyDelta = require("./apply_delta").applyDelta;
7666 var EventEmitter = require("./lib/event_emitter").EventEmitter;
7667 var Range = require("./range").Range;
7668 var Anchor = require("./anchor").Anchor;
7669
7670 var Document = function(textOrLines) {
7671 this.$lines = [""];
7672 if (textOrLines.length === 0) {
7673 this.$lines = [""];
7674 } else if (Array.isArray(textOrLines)) {
7675 this.insertMergedLines({row: 0, column: 0}, textOrLines);
7676 } else {
7677 this.insert({row: 0, column:0}, textOrLines);
7678 }
7679 };
7680
7681 (function() {
7682
7683 oop.implement(this, EventEmitter);
7684 this.setValue = function(text) {
7685 var len = this.getLength() - 1;
7686 this.remove(new Range(0, 0, len, this.getLine(len).length));
7687 this.insert({row: 0, column: 0}, text);
7688 };
7689 this.getValue = function() {
7690 return this.getAllLines().join(this.getNewLineCharacter());
7691 };
7692 this.createAnchor = function(row, column) {
7693 return new Anchor(this, row, column);
7694 };
7695 if ("aaa".split(/a/).length === 0) {
7696 this.$split = function(text) {
7697 return text.replace(/\r\n|\r/g, "\n").split("\n");
7698 };
7699 } else {
7700 this.$split = function(text) {
7701 return text.split(/\r\n|\r|\n/);
7702 };
7703 }
7704
7705
7706 this.$detectNewLine = function(text) {
7707 var match = text.match(/^.*?(\r\n|\r|\n)/m);
7708 this.$autoNewLine = match ? match[1] : "\n";
7709 this._signal("changeNewLineMode");
7710 };
7711 this.getNewLineCharacter = function() {
7712 switch (this.$newLineMode) {
7713 case "windows":
7714 return "\r\n";
7715 case "unix":
7716 return "\n";
7717 default:
7718 return this.$autoNewLine || "\n";
7719 }
7720 };
7721
7722 this.$autoNewLine = "";
7723 this.$newLineMode = "auto";
7724 this.setNewLineMode = function(newLineMode) {
7725 if (this.$newLineMode === newLineMode)
7726 return;
7727
7728 this.$newLineMode = newLineMode;
7729 this._signal("changeNewLineMode");
7730 };
7731 this.getNewLineMode = function() {
7732 return this.$newLineMode;
7733 };
7734 this.isNewLine = function(text) {
7735 return (text == "\r\n" || text == "\r" || text == "\n");
7736 };
7737 this.getLine = function(row) {
7738 return this.$lines[row] || "";
7739 };
7740 this.getLines = function(firstRow, lastRow) {
7741 return this.$lines.slice(firstRow, lastRow + 1);
7742 };
7743 this.getAllLines = function() {
7744 return this.getLines(0, this.getLength());
7745 };
7746 this.getLength = function() {
7747 return this.$lines.length;
7748 };
7749 this.getTextRange = function(range) {
7750 return this.getLinesForRange(range).join(this.getNewLineCharacter());
7751 };
7752 this.getLinesForRange = function(range) {
7753 var lines;
7754 if (range.start.row === range.end.row) {
7755 lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];
7756 } else {
7757 lines = this.getLines(range.start.row, range.end.row);
7758 lines[0] = (lines[0] || "").substring(range.start.column);
7759 var l = lines.length - 1;
7760 if (range.end.row - range.start.row == l)
7761 lines[l] = lines[l].substring(0, range.end.column);
7762 }
7763 return lines;
7764 };
7765 this.insertLines = function(row, lines) {
7766 console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead.");
7767 return this.insertFullLines(row, lines);
7768 };
7769 this.removeLines = function(firstRow, lastRow) {
7770 console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead.");
7771 return this.removeFullLines(firstRow, lastRow);
7772 };
7773 this.insertNewLine = function(position) {
7774 console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.");
7775 return this.insertMergedLines(position, ["", ""]);
7776 };
7777 this.insert = function(position, text) {
7778 if (this.getLength() <= 1)
7779 this.$detectNewLine(text);
7780
7781 return this.insertMergedLines(position, this.$split(text));
7782 };
7783 this.insertInLine = function(position, text) {
7784 var start = this.clippedPos(position.row, position.column);
7785 var end = this.pos(position.row, position.column + text.length);
7786
7787 this.applyDelta({
7788 start: start,
7789 end: end,
7790 action: "insert",
7791 lines: [text]
7792 }, true);
7793
7794 return this.clonePos(end);
7795 };
7796
7797 this.clippedPos = function(row, column) {
7798 var length = this.getLength();
7799 if (row === undefined) {
7800 row = length;
7801 } else if (row < 0) {
7802 row = 0;
7803 } else if (row >= length) {
7804 row = length - 1;
7805 column = undefined;
7806 }
7807 var line = this.getLine(row);
7808 if (column == undefined)
7809 column = line.length;
7810 column = Math.min(Math.max(column, 0), line.length);
7811 return {row: row, column: column};
7812 };
7813
7814 this.clonePos = function(pos) {
7815 return {row: pos.row, column: pos.column};
7816 };
7817
7818 this.pos = function(row, column) {
7819 return {row: row, column: column};
7820 };
7821
7822 this.$clipPosition = function(position) {
7823 var length = this.getLength();
7824 if (position.row >= length) {
7825 position.row = Math.max(0, length - 1);
7826 position.column = this.getLine(length - 1).length;
7827 } else {
7828 position.row = Math.max(0, position.row);
7829 position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);
7830 }
7831 return position;
7832 };
7833 this.insertFullLines = function(row, lines) {
7834 row = Math.min(Math.max(row, 0), this.getLength());
7835 var column = 0;
7836 if (row < this.getLength()) {
7837 lines = lines.concat([""]);
7838 column = 0;
7839 } else {
7840 lines = [""].concat(lines);
7841 row--;
7842 column = this.$lines[row].length;
7843 }
7844 this.insertMergedLines({row: row, column: column}, lines);
7845 };
7846 this.insertMergedLines = function(position, lines) {
7847 var start = this.clippedPos(position.row, position.column);
7848 var end = {
7849 row: start.row + lines.length - 1,
7850 column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length
7851 };
7852
7853 this.applyDelta({
7854 start: start,
7855 end: end,
7856 action: "insert",
7857 lines: lines
7858 });
7859
7860 return this.clonePos(end);
7861 };
7862 this.remove = function(range) {
7863 var start = this.clippedPos(range.start.row, range.start.column);
7864 var end = this.clippedPos(range.end.row, range.end.column);
7865 this.applyDelta({
7866 start: start,
7867 end: end,
7868 action: "remove",
7869 lines: this.getLinesForRange({start: start, end: end})
7870 });
7871 return this.clonePos(start);
7872 };
7873 this.removeInLine = function(row, startColumn, endColumn) {
7874 var start = this.clippedPos(row, startColumn);
7875 var end = this.clippedPos(row, endColumn);
7876
7877 this.applyDelta({
7878 start: start,
7879 end: end,
7880 action: "remove",
7881 lines: this.getLinesForRange({start: start, end: end})
7882 }, true);
7883
7884 return this.clonePos(start);
7885 };
7886 this.removeFullLines = function(firstRow, lastRow) {
7887 firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);
7888 lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1);
7889 var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;
7890 var deleteLastNewLine = lastRow < this.getLength() - 1;
7891 var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow );
7892 var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 );
7893 var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow );
7894 var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length );
7895 var range = new Range(startRow, startCol, endRow, endCol);
7896 var deletedLines = this.$lines.slice(firstRow, lastRow + 1);
7897
7898 this.applyDelta({
7899 start: range.start,
7900 end: range.end,
7901 action: "remove",
7902 lines: this.getLinesForRange(range)
7903 });
7904 return deletedLines;
7905 };
7906 this.removeNewLine = function(row) {
7907 if (row < this.getLength() - 1 && row >= 0) {
7908 this.applyDelta({
7909 start: this.pos(row, this.getLine(row).length),
7910 end: this.pos(row + 1, 0),
7911 action: "remove",
7912 lines: ["", ""]
7913 });
7914 }
7915 };
7916 this.replace = function(range, text) {
7917 if (!(range instanceof Range))
7918 range = Range.fromPoints(range.start, range.end);
7919 if (text.length === 0 && range.isEmpty())
7920 return range.start;
7921 if (text == this.getTextRange(range))
7922 return range.end;
7923
7924 this.remove(range);
7925 var end;
7926 if (text) {
7927 end = this.insert(range.start, text);
7928 }
7929 else {
7930 end = range.start;
7931 }
7932
7933 return end;
7934 };
7935 this.applyDeltas = function(deltas) {
7936 for (var i=0; i<deltas.length; i++) {
7937 this.applyDelta(deltas[i]);
7938 }
7939 };
7940 this.revertDeltas = function(deltas) {
7941 for (var i=deltas.length-1; i>=0; i--) {
7942 this.revertDelta(deltas[i]);
7943 }
7944 };
7945 this.applyDelta = function(delta, doNotValidate) {
7946 var isInsert = delta.action == "insert";
7947 if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]
7948 : !Range.comparePoints(delta.start, delta.end)) {
7949 return;
7950 }
7951
7952 if (isInsert && delta.lines.length > 20000)
7953 this.$splitAndapplyLargeDelta(delta, 20000);
7954 applyDelta(this.$lines, delta, doNotValidate);
7955 this._signal("change", delta);
7956 };
7957
7958 this.$splitAndapplyLargeDelta = function(delta, MAX) {
7959 var lines = delta.lines;
7960 var l = lines.length;
7961 var row = delta.start.row;
7962 var column = delta.start.column;
7963 var from = 0, to = 0;
7964 do {
7965 from = to;
7966 to += MAX - 1;
7967 var chunk = lines.slice(from, to);
7968 if (to > l) {
7969 delta.lines = chunk;
7970 delta.start.row = row + from;
7971 delta.start.column = column;
7972 break;
7973 }
7974 chunk.push("");
7975 this.applyDelta({
7976 start: this.pos(row + from, column),
7977 end: this.pos(row + to, column = 0),
7978 action: delta.action,
7979 lines: chunk
7980 }, true);
7981 } while(true);
7982 };
7983 this.revertDelta = function(delta) {
7984 this.applyDelta({
7985 start: this.clonePos(delta.start),
7986 end: this.clonePos(delta.end),
7987 action: (delta.action == "insert" ? "remove" : "insert"),
7988 lines: delta.lines.slice()
7989 });
7990 };
7991 this.indexToPosition = function(index, startRow) {
7992 var lines = this.$lines || this.getAllLines();
7993 var newlineLength = this.getNewLineCharacter().length;
7994 for (var i = startRow || 0, l = lines.length; i < l; i++) {
7995 index -= lines[i].length + newlineLength;
7996 if (index < 0)
7997 return {row: i, column: index + lines[i].length + newlineLength};
7998 }
7999 return {row: l-1, column: lines[l-1].length};
8000 };
8001 this.positionToIndex = function(pos, startRow) {
8002 var lines = this.$lines || this.getAllLines();
8003 var newlineLength = this.getNewLineCharacter().length;
8004 var index = 0;
8005 var row = Math.min(pos.row, lines.length);
8006 for (var i = startRow || 0; i < row; ++i)
8007 index += lines[i].length + newlineLength;
8008
8009 return index + pos.column;
8010 };
8011
8012 }).call(Document.prototype);
8013
8014 exports.Document = Document;
8015 });
8016
8017 define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) {
8018 "use strict";
8019
8020 var oop = require("./lib/oop");
8021 var EventEmitter = require("./lib/event_emitter").EventEmitter;
8022
8023 var BackgroundTokenizer = function(tokenizer, editor) {
8024 this.running = false;
8025 this.lines = [];
8026 this.states = [];
8027 this.currentLine = 0;
8028 this.tokenizer = tokenizer;
8029
8030 var self = this;
8031
8032 this.$worker = function() {
8033 if (!self.running) { return; }
8034
8035 var workerStart = new Date();
8036 var currentLine = self.currentLine;
8037 var endLine = -1;
8038 var doc = self.doc;
8039
8040 var startLine = currentLine;
8041 while (self.lines[currentLine])
8042 currentLine++;
8043
8044 var len = doc.getLength();
8045 var processedLines = 0;
8046 self.running = false;
8047 while (currentLine < len) {
8048 self.$tokenizeRow(currentLine);
8049 endLine = currentLine;
8050 do {
8051 currentLine++;
8052 } while (self.lines[currentLine]);
8053 processedLines ++;
8054 if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) {
8055 self.running = setTimeout(self.$worker, 20);
8056 break;
8057 }
8058 }
8059 self.currentLine = currentLine;
8060
8061 if (endLine == -1)
8062 endLine = currentLine;
8063
8064 if (startLine <= endLine)
8065 self.fireUpdateEvent(startLine, endLine);
8066 };
8067 };
8068
8069 (function(){
8070
8071 oop.implement(this, EventEmitter);
8072 this.setTokenizer = function(tokenizer) {
8073 this.tokenizer = tokenizer;
8074 this.lines = [];
8075 this.states = [];
8076
8077 this.start(0);
8078 };
8079 this.setDocument = function(doc) {
8080 this.doc = doc;
8081 this.lines = [];
8082 this.states = [];
8083
8084 this.stop();
8085 };
8086 this.fireUpdateEvent = function(firstRow, lastRow) {
8087 var data = {
8088 first: firstRow,
8089 last: lastRow
8090 };
8091 this._signal("update", {data: data});
8092 };
8093 this.start = function(startRow) {
8094 this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
8095 this.lines.splice(this.currentLine, this.lines.length);
8096 this.states.splice(this.currentLine, this.states.length);
8097
8098 this.stop();
8099 this.running = setTimeout(this.$worker, 700);
8100 };
8101
8102 this.scheduleStart = function() {
8103 if (!this.running)
8104 this.running = setTimeout(this.$worker, 700);
8105 };
8106
8107 this.$updateOnChange = function(delta) {
8108 var startRow = delta.start.row;
8109 var len = delta.end.row - startRow;
8110
8111 if (len === 0) {
8112 this.lines[startRow] = null;
8113 } else if (delta.action == "remove") {
8114 this.lines.splice(startRow, len + 1, null);
8115 this.states.splice(startRow, len + 1, null);
8116 } else {
8117 var args = Array(len + 1);
8118 args.unshift(startRow, 1);
8119 this.lines.splice.apply(this.lines, args);
8120 this.states.splice.apply(this.states, args);
8121 }
8122
8123 this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
8124
8125 this.stop();
8126 };
8127 this.stop = function() {
8128 if (this.running)
8129 clearTimeout(this.running);
8130 this.running = false;
8131 };
8132 this.getTokens = function(row) {
8133 return this.lines[row] || this.$tokenizeRow(row);
8134 };
8135 this.getState = function(row) {
8136 if (this.currentLine == row)
8137 this.$tokenizeRow(row);
8138 return this.states[row] || "start";
8139 };
8140
8141 this.$tokenizeRow = function(row) {
8142 var line = this.doc.getLine(row);
8143 var state = this.states[row - 1];
8144
8145 var data = this.tokenizer.getLineTokens(line, state, row);
8146
8147 if (this.states[row] + "" !== data.state + "") {
8148 this.states[row] = data.state;
8149 this.lines[row + 1] = null;
8150 if (this.currentLine > row + 1)
8151 this.currentLine = row + 1;
8152 } else if (this.currentLine == row) {
8153 this.currentLine = row + 1;
8154 }
8155
8156 return this.lines[row] = data.tokens;
8157 };
8158
8159 }).call(BackgroundTokenizer.prototype);
8160
8161 exports.BackgroundTokenizer = BackgroundTokenizer;
8162 });
8163
8164 define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) {
8165 "use strict";
8166
8167 var lang = require("./lib/lang");
8168 var oop = require("./lib/oop");
8169 var Range = require("./range").Range;
8170
8171 var SearchHighlight = function(regExp, clazz, type) {
8172 this.setRegexp(regExp);
8173 this.clazz = clazz;
8174 this.type = type || "text";
8175 };
8176
8177 (function() {
8178 this.MAX_RANGES = 500;
8179
8180 this.setRegexp = function(regExp) {
8181 if (this.regExp+"" == regExp+"")
8182 return;
8183 this.regExp = regExp;
8184 this.cache = [];
8185 };
8186
8187 this.update = function(html, markerLayer, session, config) {
8188 if (!this.regExp)
8189 return;
8190 var start = config.firstRow, end = config.lastRow;
8191
8192 for (var i = start; i <= end; i++) {
8193 var ranges = this.cache[i];
8194 if (ranges == null) {
8195 ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);
8196 if (ranges.length > this.MAX_RANGES)
8197 ranges = ranges.slice(0, this.MAX_RANGES);
8198 ranges = ranges.map(function(match) {
8199 return new Range(i, match.offset, i, match.offset + match.length);
8200 });
8201 this.cache[i] = ranges.length ? ranges : "";
8202 }
8203
8204 for (var j = ranges.length; j --; ) {
8205 markerLayer.drawSingleLineMarker(
8206 html, ranges[j].toScreenRange(session), this.clazz, config);
8207 }
8208 }
8209 };
8210
8211 }).call(SearchHighlight.prototype);
8212
8213 exports.SearchHighlight = SearchHighlight;
8214 });
8215
8216 define("ace/edit_session/fold_line",["require","exports","module","ace/range"], function(require, exports, module) {
8217 "use strict";
8218
8219 var Range = require("../range").Range;
8220 function FoldLine(foldData, folds) {
8221 this.foldData = foldData;
8222 if (Array.isArray(folds)) {
8223 this.folds = folds;
8224 } else {
8225 folds = this.folds = [ folds ];
8226 }
8227
8228 var last = folds[folds.length - 1];
8229 this.range = new Range(folds[0].start.row, folds[0].start.column,
8230 last.end.row, last.end.column);
8231 this.start = this.range.start;
8232 this.end = this.range.end;
8233
8234 this.folds.forEach(function(fold) {
8235 fold.setFoldLine(this);
8236 }, this);
8237 }
8238
8239 (function() {
8240 this.shiftRow = function(shift) {
8241 this.start.row += shift;
8242 this.end.row += shift;
8243 this.folds.forEach(function(fold) {
8244 fold.start.row += shift;
8245 fold.end.row += shift;
8246 });
8247 };
8248
8249 this.addFold = function(fold) {
8250 if (fold.sameRow) {
8251 if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
8252 throw new Error("Can't add a fold to this FoldLine as it has no connection");
8253 }
8254 this.folds.push(fold);
8255 this.folds.sort(function(a, b) {
8256 return -a.range.compareEnd(b.start.row, b.start.column);
8257 });
8258 if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
8259 this.end.row = fold.end.row;
8260 this.end.column = fold.end.column;
8261 } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
8262 this.start.row = fold.start.row;
8263 this.start.column = fold.start.column;
8264 }
8265 } else if (fold.start.row == this.end.row) {
8266 this.folds.push(fold);
8267 this.end.row = fold.end.row;
8268 this.end.column = fold.end.column;
8269 } else if (fold.end.row == this.start.row) {
8270 this.folds.unshift(fold);
8271 this.start.row = fold.start.row;
8272 this.start.column = fold.start.column;
8273 } else {
8274 throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
8275 }
8276 fold.foldLine = this;
8277 };
8278
8279 this.containsRow = function(row) {
8280 return row >= this.start.row && row <= this.end.row;
8281 };
8282
8283 this.walk = function(callback, endRow, endColumn) {
8284 var lastEnd = 0,
8285 folds = this.folds,
8286 fold,
8287 cmp, stop, isNewRow = true;
8288
8289 if (endRow == null) {
8290 endRow = this.end.row;
8291 endColumn = this.end.column;
8292 }
8293
8294 for (var i = 0; i < folds.length; i++) {
8295 fold = folds[i];
8296
8297 cmp = fold.range.compareStart(endRow, endColumn);
8298 if (cmp == -1) {
8299 callback(null, endRow, endColumn, lastEnd, isNewRow);
8300 return;
8301 }
8302
8303 stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
8304 stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
8305 if (stop || cmp === 0) {
8306 return;
8307 }
8308 isNewRow = !fold.sameRow;
8309 lastEnd = fold.end.column;
8310 }
8311 callback(null, endRow, endColumn, lastEnd, isNewRow);
8312 };
8313
8314 this.getNextFoldTo = function(row, column) {
8315 var fold, cmp;
8316 for (var i = 0; i < this.folds.length; i++) {
8317 fold = this.folds[i];
8318 cmp = fold.range.compareEnd(row, column);
8319 if (cmp == -1) {
8320 return {
8321 fold: fold,
8322 kind: "after"
8323 };
8324 } else if (cmp === 0) {
8325 return {
8326 fold: fold,
8327 kind: "inside"
8328 };
8329 }
8330 }
8331 return null;
8332 };
8333
8334 this.addRemoveChars = function(row, column, len) {
8335 var ret = this.getNextFoldTo(row, column),
8336 fold, folds;
8337 if (ret) {
8338 fold = ret.fold;
8339 if (ret.kind == "inside"
8340 && fold.start.column != column
8341 && fold.start.row != row)
8342 {
8343 window.console && window.console.log(row, column, fold);
8344 } else if (fold.start.row == row) {
8345 folds = this.folds;
8346 var i = folds.indexOf(fold);
8347 if (i === 0) {
8348 this.start.column += len;
8349 }
8350 for (i; i < folds.length; i++) {
8351 fold = folds[i];
8352 fold.start.column += len;
8353 if (!fold.sameRow) {
8354 return;
8355 }
8356 fold.end.column += len;
8357 }
8358 this.end.column += len;
8359 }
8360 }
8361 };
8362
8363 this.split = function(row, column) {
8364 var pos = this.getNextFoldTo(row, column);
8365
8366 if (!pos || pos.kind == "inside")
8367 return null;
8368
8369 var fold = pos.fold;
8370 var folds = this.folds;
8371 var foldData = this.foldData;
8372
8373 var i = folds.indexOf(fold);
8374 var foldBefore = folds[i - 1];
8375 this.end.row = foldBefore.end.row;
8376 this.end.column = foldBefore.end.column;
8377 folds = folds.splice(i, folds.length - i);
8378
8379 var newFoldLine = new FoldLine(foldData, folds);
8380 foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
8381 return newFoldLine;
8382 };
8383
8384 this.merge = function(foldLineNext) {
8385 var folds = foldLineNext.folds;
8386 for (var i = 0; i < folds.length; i++) {
8387 this.addFold(folds[i]);
8388 }
8389 var foldData = this.foldData;
8390 foldData.splice(foldData.indexOf(foldLineNext), 1);
8391 };
8392
8393 this.toString = function() {
8394 var ret = [this.range.toString() + ": [" ];
8395
8396 this.folds.forEach(function(fold) {
8397 ret.push(" " + fold.toString());
8398 });
8399 ret.push("]");
8400 return ret.join("\n");
8401 };
8402
8403 this.idxToPosition = function(idx) {
8404 var lastFoldEndColumn = 0;
8405
8406 for (var i = 0; i < this.folds.length; i++) {
8407 var fold = this.folds[i];
8408
8409 idx -= fold.start.column - lastFoldEndColumn;
8410 if (idx < 0) {
8411 return {
8412 row: fold.start.row,
8413 column: fold.start.column + idx
8414 };
8415 }
8416
8417 idx -= fold.placeholder.length;
8418 if (idx < 0) {
8419 return fold.start;
8420 }
8421
8422 lastFoldEndColumn = fold.end.column;
8423 }
8424
8425 return {
8426 row: this.end.row,
8427 column: this.end.column + idx
8428 };
8429 };
8430 }).call(FoldLine.prototype);
8431
8432 exports.FoldLine = FoldLine;
8433 });
8434
8435 define("ace/range_list",["require","exports","module","ace/range"], function(require, exports, module) {
8436 "use strict";
8437 var Range = require("./range").Range;
8438 var comparePoints = Range.comparePoints;
8439
8440 var RangeList = function() {
8441 this.ranges = [];
8442 };
8443
8444 (function() {
8445 this.comparePoints = comparePoints;
8446
8447 this.pointIndex = function(pos, excludeEdges, startIndex) {
8448 var list = this.ranges;
8449
8450 for (var i = startIndex || 0; i < list.length; i++) {
8451 var range = list[i];
8452 var cmpEnd = comparePoints(pos, range.end);
8453 if (cmpEnd > 0)
8454 continue;
8455 var cmpStart = comparePoints(pos, range.start);
8456 if (cmpEnd === 0)
8457 return excludeEdges && cmpStart !== 0 ? -i-2 : i;
8458 if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
8459 return i;
8460
8461 return -i-1;
8462 }
8463 return -i - 1;
8464 };
8465
8466 this.add = function(range) {
8467 var excludeEdges = !range.isEmpty();
8468 var startIndex = this.pointIndex(range.start, excludeEdges);
8469 if (startIndex < 0)
8470 startIndex = -startIndex - 1;
8471
8472 var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
8473
8474 if (endIndex < 0)
8475 endIndex = -endIndex - 1;
8476 else
8477 endIndex++;
8478 return this.ranges.splice(startIndex, endIndex - startIndex, range);
8479 };
8480
8481 this.addList = function(list) {
8482 var removed = [];
8483 for (var i = list.length; i--; ) {
8484 removed.push.apply(removed, this.add(list[i]));
8485 }
8486 return removed;
8487 };
8488
8489 this.substractPoint = function(pos) {
8490 var i = this.pointIndex(pos);
8491
8492 if (i >= 0)
8493 return this.ranges.splice(i, 1);
8494 };
8495 this.merge = function() {
8496 var removed = [];
8497 var list = this.ranges;
8498
8499 list = list.sort(function(a, b) {
8500 return comparePoints(a.start, b.start);
8501 });
8502
8503 var next = list[0], range;
8504 for (var i = 1; i < list.length; i++) {
8505 range = next;
8506 next = list[i];
8507 var cmp = comparePoints(range.end, next.start);
8508 if (cmp < 0)
8509 continue;
8510
8511 if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
8512 continue;
8513
8514 if (comparePoints(range.end, next.end) < 0) {
8515 range.end.row = next.end.row;
8516 range.end.column = next.end.column;
8517 }
8518
8519 list.splice(i, 1);
8520 removed.push(next);
8521 next = range;
8522 i--;
8523 }
8524
8525 this.ranges = list;
8526
8527 return removed;
8528 };
8529
8530 this.contains = function(row, column) {
8531 return this.pointIndex({row: row, column: column}) >= 0;
8532 };
8533
8534 this.containsPoint = function(pos) {
8535 return this.pointIndex(pos) >= 0;
8536 };
8537
8538 this.rangeAtPoint = function(pos) {
8539 var i = this.pointIndex(pos);
8540 if (i >= 0)
8541 return this.ranges[i];
8542 };
8543
8544
8545 this.clipRows = function(startRow, endRow) {
8546 var list = this.ranges;
8547 if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)
8548 return [];
8549
8550 var startIndex = this.pointIndex({row: startRow, column: 0});
8551 if (startIndex < 0)
8552 startIndex = -startIndex - 1;
8553 var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);
8554 if (endIndex < 0)
8555 endIndex = -endIndex - 1;
8556
8557 var clipped = [];
8558 for (var i = startIndex; i < endIndex; i++) {
8559 clipped.push(list[i]);
8560 }
8561 return clipped;
8562 };
8563
8564 this.removeAll = function() {
8565 return this.ranges.splice(0, this.ranges.length);
8566 };
8567
8568 this.attach = function(session) {
8569 if (this.session)
8570 this.detach();
8571
8572 this.session = session;
8573 this.onChange = this.$onChange.bind(this);
8574
8575 this.session.on('change', this.onChange);
8576 };
8577
8578 this.detach = function() {
8579 if (!this.session)
8580 return;
8581 this.session.removeListener('change', this.onChange);
8582 this.session = null;
8583 };
8584
8585 this.$onChange = function(delta) {
8586 if (delta.action == "insert"){
8587 var start = delta.start;
8588 var end = delta.end;
8589 } else {
8590 var end = delta.start;
8591 var start = delta.end;
8592 }
8593 var startRow = start.row;
8594 var endRow = end.row;
8595 var lineDif = endRow - startRow;
8596
8597 var colDiff = -start.column + end.column;
8598 var ranges = this.ranges;
8599
8600 for (var i = 0, n = ranges.length; i < n; i++) {
8601 var r = ranges[i];
8602 if (r.end.row < startRow)
8603 continue;
8604 if (r.start.row > startRow)
8605 break;
8606
8607 if (r.start.row == startRow && r.start.column >= start.column ) {
8608 if (r.start.column == start.column && this.$insertRight) {
8609 } else {
8610 r.start.column += colDiff;
8611 r.start.row += lineDif;
8612 }
8613 }
8614 if (r.end.row == startRow && r.end.column >= start.column) {
8615 if (r.end.column == start.column && this.$insertRight) {
8616 continue;
8617 }
8618 if (r.end.column == start.column && colDiff > 0 && i < n - 1) {
8619 if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
8620 r.end.column -= colDiff;
8621 }
8622 r.end.column += colDiff;
8623 r.end.row += lineDif;
8624 }
8625 }
8626
8627 if (lineDif != 0 && i < n) {
8628 for (; i < n; i++) {
8629 var r = ranges[i];
8630 r.start.row += lineDif;
8631 r.end.row += lineDif;
8632 }
8633 }
8634 };
8635
8636 }).call(RangeList.prototype);
8637
8638 exports.RangeList = RangeList;
8639 });
8640
8641 define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"], function(require, exports, module) {
8642 "use strict";
8643
8644 var Range = require("../range").Range;
8645 var RangeList = require("../range_list").RangeList;
8646 var oop = require("../lib/oop");
8647 var Fold = exports.Fold = function(range, placeholder) {
8648 this.foldLine = null;
8649 this.placeholder = placeholder;
8650 this.range = range;
8651 this.start = range.start;
8652 this.end = range.end;
8653
8654 this.sameRow = range.start.row == range.end.row;
8655 this.subFolds = this.ranges = [];
8656 };
8657
8658 oop.inherits(Fold, RangeList);
8659
8660 (function() {
8661
8662 this.toString = function() {
8663 return '"' + this.placeholder + '" ' + this.range.toString();
8664 };
8665
8666 this.setFoldLine = function(foldLine) {
8667 this.foldLine = foldLine;
8668 this.subFolds.forEach(function(fold) {
8669 fold.setFoldLine(foldLine);
8670 });
8671 };
8672
8673 this.clone = function() {
8674 var range = this.range.clone();
8675 var fold = new Fold(range, this.placeholder);
8676 this.subFolds.forEach(function(subFold) {
8677 fold.subFolds.push(subFold.clone());
8678 });
8679 fold.collapseChildren = this.collapseChildren;
8680 return fold;
8681 };
8682
8683 this.addSubFold = function(fold) {
8684 if (this.range.isEqual(fold))
8685 return;
8686
8687 if (!this.range.containsRange(fold))
8688 throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
8689 consumeRange(fold, this.start);
8690
8691 var row = fold.start.row, column = fold.start.column;
8692 for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
8693 cmp = this.subFolds[i].range.compare(row, column);
8694 if (cmp != 1)
8695 break;
8696 }
8697 var afterStart = this.subFolds[i];
8698
8699 if (cmp == 0)
8700 return afterStart.addSubFold(fold);
8701 var row = fold.range.end.row, column = fold.range.end.column;
8702 for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
8703 cmp = this.subFolds[j].range.compare(row, column);
8704 if (cmp != 1)
8705 break;
8706 }
8707 var afterEnd = this.subFolds[j];
8708
8709 if (cmp == 0)
8710 throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
8711
8712 var consumedFolds = this.subFolds.splice(i, j - i, fold);
8713 fold.setFoldLine(this.foldLine);
8714
8715 return fold;
8716 };
8717
8718 this.restoreRange = function(range) {
8719 return restoreRange(range, this.start);
8720 };
8721
8722 }).call(Fold.prototype);
8723
8724 function consumePoint(point, anchor) {
8725 point.row -= anchor.row;
8726 if (point.row == 0)
8727 point.column -= anchor.column;
8728 }
8729 function consumeRange(range, anchor) {
8730 consumePoint(range.start, anchor);
8731 consumePoint(range.end, anchor);
8732 }
8733 function restorePoint(point, anchor) {
8734 if (point.row == 0)
8735 point.column += anchor.column;
8736 point.row += anchor.row;
8737 }
8738 function restoreRange(range, anchor) {
8739 restorePoint(range.start, anchor);
8740 restorePoint(range.end, anchor);
8741 }
8742
8743 });
8744
8745 define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"], function(require, exports, module) {
8746 "use strict";
8747
8748 var Range = require("../range").Range;
8749 var FoldLine = require("./fold_line").FoldLine;
8750 var Fold = require("./fold").Fold;
8751 var TokenIterator = require("../token_iterator").TokenIterator;
8752
8753 function Folding() {
8754 this.getFoldAt = function(row, column, side) {
8755 var foldLine = this.getFoldLine(row);
8756 if (!foldLine)
8757 return null;
8758
8759 var folds = foldLine.folds;
8760 for (var i = 0; i < folds.length; i++) {
8761 var fold = folds[i];
8762 if (fold.range.contains(row, column)) {
8763 if (side == 1 && fold.range.isEnd(row, column)) {
8764 continue;
8765 } else if (side == -1 && fold.range.isStart(row, column)) {
8766 continue;
8767 }
8768 return fold;
8769 }
8770 }
8771 };
8772 this.getFoldsInRange = function(range) {
8773 var start = range.start;
8774 var end = range.end;
8775 var foldLines = this.$foldData;
8776 var foundFolds = [];
8777
8778 start.column += 1;
8779 end.column -= 1;
8780
8781 for (var i = 0; i < foldLines.length; i++) {
8782 var cmp = foldLines[i].range.compareRange(range);
8783 if (cmp == 2) {
8784 continue;
8785 }
8786 else if (cmp == -2) {
8787 break;
8788 }
8789
8790 var folds = foldLines[i].folds;
8791 for (var j = 0; j < folds.length; j++) {
8792 var fold = folds[j];
8793 cmp = fold.range.compareRange(range);
8794 if (cmp == -2) {
8795 break;
8796 } else if (cmp == 2) {
8797 continue;
8798 } else
8799 if (cmp == 42) {
8800 break;
8801 }
8802 foundFolds.push(fold);
8803 }
8804 }
8805 start.column -= 1;
8806 end.column += 1;
8807
8808 return foundFolds;
8809 };
8810
8811 this.getFoldsInRangeList = function(ranges) {
8812 if (Array.isArray(ranges)) {
8813 var folds = [];
8814 ranges.forEach(function(range) {
8815 folds = folds.concat(this.getFoldsInRange(range));
8816 }, this);
8817 } else {
8818 var folds = this.getFoldsInRange(ranges);
8819 }
8820 return folds;
8821 };
8822 this.getAllFolds = function() {
8823 var folds = [];
8824 var foldLines = this.$foldData;
8825
8826 for (var i = 0; i < foldLines.length; i++)
8827 for (var j = 0; j < foldLines[i].folds.length; j++)
8828 folds.push(foldLines[i].folds[j]);
8829
8830 return folds;
8831 };
8832 this.getFoldStringAt = function(row, column, trim, foldLine) {
8833 foldLine = foldLine || this.getFoldLine(row);
8834 if (!foldLine)
8835 return null;
8836
8837 var lastFold = {
8838 end: { column: 0 }
8839 };
8840 var str, fold;
8841 for (var i = 0; i < foldLine.folds.length; i++) {
8842 fold = foldLine.folds[i];
8843 var cmp = fold.range.compareEnd(row, column);
8844 if (cmp == -1) {
8845 str = this
8846 .getLine(fold.start.row)
8847 .substring(lastFold.end.column, fold.start.column);
8848 break;
8849 }
8850 else if (cmp === 0) {
8851 return null;
8852 }
8853 lastFold = fold;
8854 }
8855 if (!str)
8856 str = this.getLine(fold.start.row).substring(lastFold.end.column);
8857
8858 if (trim == -1)
8859 return str.substring(0, column - lastFold.end.column);
8860 else if (trim == 1)
8861 return str.substring(column - lastFold.end.column);
8862 else
8863 return str;
8864 };
8865
8866 this.getFoldLine = function(docRow, startFoldLine) {
8867 var foldData = this.$foldData;
8868 var i = 0;
8869 if (startFoldLine)
8870 i = foldData.indexOf(startFoldLine);
8871 if (i == -1)
8872 i = 0;
8873 for (i; i < foldData.length; i++) {
8874 var foldLine = foldData[i];
8875 if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
8876 return foldLine;
8877 } else if (foldLine.end.row > docRow) {
8878 return null;
8879 }
8880 }
8881 return null;
8882 };
8883 this.getNextFoldLine = function(docRow, startFoldLine) {
8884 var foldData = this.$foldData;
8885 var i = 0;
8886 if (startFoldLine)
8887 i = foldData.indexOf(startFoldLine);
8888 if (i == -1)
8889 i = 0;
8890 for (i; i < foldData.length; i++) {
8891 var foldLine = foldData[i];
8892 if (foldLine.end.row >= docRow) {
8893 return foldLine;
8894 }
8895 }
8896 return null;
8897 };
8898
8899 this.getFoldedRowCount = function(first, last) {
8900 var foldData = this.$foldData, rowCount = last-first+1;
8901 for (var i = 0; i < foldData.length; i++) {
8902 var foldLine = foldData[i],
8903 end = foldLine.end.row,
8904 start = foldLine.start.row;
8905 if (end >= last) {
8906 if (start < last) {
8907 if (start >= first)
8908 rowCount -= last-start;
8909 else
8910 rowCount = 0; // in one fold
8911 }
8912 break;
8913 } else if (end >= first){
8914 if (start >= first) // fold inside range
8915 rowCount -= end-start;
8916 else
8917 rowCount -= end-first+1;
8918 }
8919 }
8920 return rowCount;
8921 };
8922
8923 this.$addFoldLine = function(foldLine) {
8924 this.$foldData.push(foldLine);
8925 this.$foldData.sort(function(a, b) {
8926 return a.start.row - b.start.row;
8927 });
8928 return foldLine;
8929 };
8930 this.addFold = function(placeholder, range) {
8931 var foldData = this.$foldData;
8932 var added = false;
8933 var fold;
8934
8935 if (placeholder instanceof Fold)
8936 fold = placeholder;
8937 else {
8938 fold = new Fold(range, placeholder);
8939 fold.collapseChildren = range.collapseChildren;
8940 }
8941 this.$clipRangeToDocument(fold.range);
8942
8943 var startRow = fold.start.row;
8944 var startColumn = fold.start.column;
8945 var endRow = fold.end.row;
8946 var endColumn = fold.end.column;
8947 if (!(startRow < endRow ||
8948 startRow == endRow && startColumn <= endColumn - 2))
8949 throw new Error("The range has to be at least 2 characters width");
8950
8951 var startFold = this.getFoldAt(startRow, startColumn, 1);
8952 var endFold = this.getFoldAt(endRow, endColumn, -1);
8953 if (startFold && endFold == startFold)
8954 return startFold.addSubFold(fold);
8955
8956 if (startFold && !startFold.range.isStart(startRow, startColumn))
8957 this.removeFold(startFold);
8958
8959 if (endFold && !endFold.range.isEnd(endRow, endColumn))
8960 this.removeFold(endFold);
8961 var folds = this.getFoldsInRange(fold.range);
8962 if (folds.length > 0) {
8963 this.removeFolds(folds);
8964 folds.forEach(function(subFold) {
8965 fold.addSubFold(subFold);
8966 });
8967 }
8968
8969 for (var i = 0; i < foldData.length; i++) {
8970 var foldLine = foldData[i];
8971 if (endRow == foldLine.start.row) {
8972 foldLine.addFold(fold);
8973 added = true;
8974 break;
8975 } else if (startRow == foldLine.end.row) {
8976 foldLine.addFold(fold);
8977 added = true;
8978 if (!fold.sameRow) {
8979 var foldLineNext = foldData[i + 1];
8980 if (foldLineNext && foldLineNext.start.row == endRow) {
8981 foldLine.merge(foldLineNext);
8982 break;
8983 }
8984 }
8985 break;
8986 } else if (endRow <= foldLine.start.row) {
8987 break;
8988 }
8989 }
8990
8991 if (!added)
8992 foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
8993
8994 if (this.$useWrapMode)
8995 this.$updateWrapData(foldLine.start.row, foldLine.start.row);
8996 else
8997 this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);
8998 this.$modified = true;
8999 this._signal("changeFold", { data: fold, action: "add" });
9000
9001 return fold;
9002 };
9003
9004 this.addFolds = function(folds) {
9005 folds.forEach(function(fold) {
9006 this.addFold(fold);
9007 }, this);
9008 };
9009
9010 this.removeFold = function(fold) {
9011 var foldLine = fold.foldLine;
9012 var startRow = foldLine.start.row;
9013 var endRow = foldLine.end.row;
9014
9015 var foldLines = this.$foldData;
9016 var folds = foldLine.folds;
9017 if (folds.length == 1) {
9018 foldLines.splice(foldLines.indexOf(foldLine), 1);
9019 } else
9020 if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
9021 folds.pop();
9022 foldLine.end.row = folds[folds.length - 1].end.row;
9023 foldLine.end.column = folds[folds.length - 1].end.column;
9024 } else
9025 if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
9026 folds.shift();
9027 foldLine.start.row = folds[0].start.row;
9028 foldLine.start.column = folds[0].start.column;
9029 } else
9030 if (fold.sameRow) {
9031 folds.splice(folds.indexOf(fold), 1);
9032 } else
9033 {
9034 var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
9035 folds = newFoldLine.folds;
9036 folds.shift();
9037 newFoldLine.start.row = folds[0].start.row;
9038 newFoldLine.start.column = folds[0].start.column;
9039 }
9040
9041 if (!this.$updating) {
9042 if (this.$useWrapMode)
9043 this.$updateWrapData(startRow, endRow);
9044 else
9045 this.$updateRowLengthCache(startRow, endRow);
9046 }
9047 this.$modified = true;
9048 this._signal("changeFold", { data: fold, action: "remove" });
9049 };
9050
9051 this.removeFolds = function(folds) {
9052 var cloneFolds = [];
9053 for (var i = 0; i < folds.length; i++) {
9054 cloneFolds.push(folds[i]);
9055 }
9056
9057 cloneFolds.forEach(function(fold) {
9058 this.removeFold(fold);
9059 }, this);
9060 this.$modified = true;
9061 };
9062
9063 this.expandFold = function(fold) {
9064 this.removeFold(fold);
9065 fold.subFolds.forEach(function(subFold) {
9066 fold.restoreRange(subFold);
9067 this.addFold(subFold);
9068 }, this);
9069 if (fold.collapseChildren > 0) {
9070 this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
9071 }
9072 fold.subFolds = [];
9073 };
9074
9075 this.expandFolds = function(folds) {
9076 folds.forEach(function(fold) {
9077 this.expandFold(fold);
9078 }, this);
9079 };
9080
9081 this.unfold = function(location, expandInner) {
9082 var range, folds;
9083 if (location == null) {
9084 range = new Range(0, 0, this.getLength(), 0);
9085 expandInner = true;
9086 } else if (typeof location == "number")
9087 range = new Range(location, 0, location, this.getLine(location).length);
9088 else if ("row" in location)
9089 range = Range.fromPoints(location, location);
9090 else
9091 range = location;
9092
9093 folds = this.getFoldsInRangeList(range);
9094 if (expandInner) {
9095 this.removeFolds(folds);
9096 } else {
9097 var subFolds = folds;
9098 while (subFolds.length) {
9099 this.expandFolds(subFolds);
9100 subFolds = this.getFoldsInRangeList(range);
9101 }
9102 }
9103 if (folds.length)
9104 return folds;
9105 };
9106 this.isRowFolded = function(docRow, startFoldRow) {
9107 return !!this.getFoldLine(docRow, startFoldRow);
9108 };
9109
9110 this.getRowFoldEnd = function(docRow, startFoldRow) {
9111 var foldLine = this.getFoldLine(docRow, startFoldRow);
9112 return foldLine ? foldLine.end.row : docRow;
9113 };
9114
9115 this.getRowFoldStart = function(docRow, startFoldRow) {
9116 var foldLine = this.getFoldLine(docRow, startFoldRow);
9117 return foldLine ? foldLine.start.row : docRow;
9118 };
9119
9120 this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
9121 if (startRow == null)
9122 startRow = foldLine.start.row;
9123 if (startColumn == null)
9124 startColumn = 0;
9125 if (endRow == null)
9126 endRow = foldLine.end.row;
9127 if (endColumn == null)
9128 endColumn = this.getLine(endRow).length;
9129 var doc = this.doc;
9130 var textLine = "";
9131
9132 foldLine.walk(function(placeholder, row, column, lastColumn) {
9133 if (row < startRow)
9134 return;
9135 if (row == startRow) {
9136 if (column < startColumn)
9137 return;
9138 lastColumn = Math.max(startColumn, lastColumn);
9139 }
9140
9141 if (placeholder != null) {
9142 textLine += placeholder;
9143 } else {
9144 textLine += doc.getLine(row).substring(lastColumn, column);
9145 }
9146 }, endRow, endColumn);
9147 return textLine;
9148 };
9149
9150 this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
9151 var foldLine = this.getFoldLine(row);
9152
9153 if (!foldLine) {
9154 var line;
9155 line = this.doc.getLine(row);
9156 return line.substring(startColumn || 0, endColumn || line.length);
9157 } else {
9158 return this.getFoldDisplayLine(
9159 foldLine, row, endColumn, startRow, startColumn);
9160 }
9161 };
9162
9163 this.$cloneFoldData = function() {
9164 var fd = [];
9165 fd = this.$foldData.map(function(foldLine) {
9166 var folds = foldLine.folds.map(function(fold) {
9167 return fold.clone();
9168 });
9169 return new FoldLine(fd, folds);
9170 });
9171
9172 return fd;
9173 };
9174
9175 this.toggleFold = function(tryToUnfold) {
9176 var selection = this.selection;
9177 var range = selection.getRange();
9178 var fold;
9179 var bracketPos;
9180
9181 if (range.isEmpty()) {
9182 var cursor = range.start;
9183 fold = this.getFoldAt(cursor.row, cursor.column);
9184
9185 if (fold) {
9186 this.expandFold(fold);
9187 return;
9188 } else if (bracketPos = this.findMatchingBracket(cursor)) {
9189 if (range.comparePoint(bracketPos) == 1) {
9190 range.end = bracketPos;
9191 } else {
9192 range.start = bracketPos;
9193 range.start.column++;
9194 range.end.column--;
9195 }
9196 } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
9197 if (range.comparePoint(bracketPos) == 1)
9198 range.end = bracketPos;
9199 else
9200 range.start = bracketPos;
9201
9202 range.start.column++;
9203 } else {
9204 range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
9205 }
9206 } else {
9207 var folds = this.getFoldsInRange(range);
9208 if (tryToUnfold && folds.length) {
9209 this.expandFolds(folds);
9210 return;
9211 } else if (folds.length == 1 ) {
9212 fold = folds[0];
9213 }
9214 }
9215
9216 if (!fold)
9217 fold = this.getFoldAt(range.start.row, range.start.column);
9218
9219 if (fold && fold.range.toString() == range.toString()) {
9220 this.expandFold(fold);
9221 return;
9222 }
9223
9224 var placeholder = "...";
9225 if (!range.isMultiLine()) {
9226 placeholder = this.getTextRange(range);
9227 if (placeholder.length < 4)
9228 return;
9229 placeholder = placeholder.trim().substring(0, 2) + "..";
9230 }
9231
9232 this.addFold(placeholder, range);
9233 };
9234
9235 this.getCommentFoldRange = function(row, column, dir) {
9236 var iterator = new TokenIterator(this, row, column);
9237 var token = iterator.getCurrentToken();
9238 var type = token.type;
9239 if (token && /^comment|string/.test(type)) {
9240 type = type.match(/comment|string/)[0];
9241 if (type == "comment")
9242 type += "|doc-start";
9243 var re = new RegExp(type);
9244 var range = new Range();
9245 if (dir != 1) {
9246 do {
9247 token = iterator.stepBackward();
9248 } while (token && re.test(token.type));
9249 iterator.stepForward();
9250 }
9251
9252 range.start.row = iterator.getCurrentTokenRow();
9253 range.start.column = iterator.getCurrentTokenColumn() + 2;
9254
9255 iterator = new TokenIterator(this, row, column);
9256
9257 if (dir != -1) {
9258 var lastRow = -1;
9259 do {
9260 token = iterator.stepForward();
9261 if (lastRow == -1) {
9262 var state = this.getState(iterator.$row);
9263 if (!re.test(state))
9264 lastRow = iterator.$row;
9265 } else if (iterator.$row > lastRow) {
9266 break;
9267 }
9268 } while (token && re.test(token.type));
9269 token = iterator.stepBackward();
9270 } else
9271 token = iterator.getCurrentToken();
9272
9273 range.end.row = iterator.getCurrentTokenRow();
9274 range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
9275 return range;
9276 }
9277 };
9278
9279 this.foldAll = function(startRow, endRow, depth) {
9280 if (depth == undefined)
9281 depth = 100000; // JSON.stringify doesn't hanle Infinity
9282 var foldWidgets = this.foldWidgets;
9283 if (!foldWidgets)
9284 return; // mode doesn't support folding
9285 endRow = endRow || this.getLength();
9286 startRow = startRow || 0;
9287 for (var row = startRow; row < endRow; row++) {
9288 if (foldWidgets[row] == null)
9289 foldWidgets[row] = this.getFoldWidget(row);
9290 if (foldWidgets[row] != "start")
9291 continue;
9292
9293 var range = this.getFoldWidgetRange(row);
9294 if (range && range.isMultiLine()
9295 && range.end.row <= endRow
9296 && range.start.row >= startRow
9297 ) {
9298 row = range.end.row;
9299 try {
9300 var fold = this.addFold("...", range);
9301 if (fold)
9302 fold.collapseChildren = depth;
9303 } catch(e) {}
9304 }
9305 }
9306 };
9307 this.$foldStyles = {
9308 "manual": 1,
9309 "markbegin": 1,
9310 "markbeginend": 1
9311 };
9312 this.$foldStyle = "markbegin";
9313 this.setFoldStyle = function(style) {
9314 if (!this.$foldStyles[style])
9315 throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]");
9316
9317 if (this.$foldStyle == style)
9318 return;
9319
9320 this.$foldStyle = style;
9321
9322 if (style == "manual")
9323 this.unfold();
9324 var mode = this.$foldMode;
9325 this.$setFolding(null);
9326 this.$setFolding(mode);
9327 };
9328
9329 this.$setFolding = function(foldMode) {
9330 if (this.$foldMode == foldMode)
9331 return;
9332
9333 this.$foldMode = foldMode;
9334
9335 this.off('change', this.$updateFoldWidgets);
9336 this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);
9337 this._signal("changeAnnotation");
9338
9339 if (!foldMode || this.$foldStyle == "manual") {
9340 this.foldWidgets = null;
9341 return;
9342 }
9343
9344 this.foldWidgets = [];
9345 this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);
9346 this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);
9347
9348 this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
9349 this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this);
9350 this.on('change', this.$updateFoldWidgets);
9351 this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);
9352 };
9353
9354 this.getParentFoldRangeData = function (row, ignoreCurrent) {
9355 var fw = this.foldWidgets;
9356 if (!fw || (ignoreCurrent && fw[row]))
9357 return {};
9358
9359 var i = row - 1, firstRange;
9360 while (i >= 0) {
9361 var c = fw[i];
9362 if (c == null)
9363 c = fw[i] = this.getFoldWidget(i);
9364
9365 if (c == "start") {
9366 var range = this.getFoldWidgetRange(i);
9367 if (!firstRange)
9368 firstRange = range;
9369 if (range && range.end.row >= row)
9370 break;
9371 }
9372 i--;
9373 }
9374
9375 return {
9376 range: i !== -1 && range,
9377 firstRange: firstRange
9378 };
9379 };
9380
9381 this.onFoldWidgetClick = function(row, e) {
9382 e = e.domEvent;
9383 var options = {
9384 children: e.shiftKey,
9385 all: e.ctrlKey || e.metaKey,
9386 siblings: e.altKey
9387 };
9388
9389 var range = this.$toggleFoldWidget(row, options);
9390 if (!range) {
9391 var el = (e.target || e.srcElement);
9392 if (el && /ace_fold-widget/.test(el.className))
9393 el.className += " ace_invalid";
9394 }
9395 };
9396
9397 this.$toggleFoldWidget = function(row, options) {
9398 if (!this.getFoldWidget)
9399 return;
9400 var type = this.getFoldWidget(row);
9401 var line = this.getLine(row);
9402
9403 var dir = type === "end" ? -1 : 1;
9404 var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
9405
9406 if (fold) {
9407 if (options.children || options.all)
9408 this.removeFold(fold);
9409 else
9410 this.expandFold(fold);
9411 return fold;
9412 }
9413
9414 var range = this.getFoldWidgetRange(row, true);
9415 if (range && !range.isMultiLine()) {
9416 fold = this.getFoldAt(range.start.row, range.start.column, 1);
9417 if (fold && range.isEqual(fold.range)) {
9418 this.removeFold(fold);
9419 return fold;
9420 }
9421 }
9422
9423 if (options.siblings) {
9424 var data = this.getParentFoldRangeData(row);
9425 if (data.range) {
9426 var startRow = data.range.start.row + 1;
9427 var endRow = data.range.end.row;
9428 }
9429 this.foldAll(startRow, endRow, options.all ? 10000 : 0);
9430 } else if (options.children) {
9431 endRow = range ? range.end.row : this.getLength();
9432 this.foldAll(row + 1, endRow, options.all ? 10000 : 0);
9433 } else if (range) {
9434 if (options.all)
9435 range.collapseChildren = 10000;
9436 this.addFold("...", range);
9437 }
9438
9439 return range;
9440 };
9441
9442
9443
9444 this.toggleFoldWidget = function(toggleParent) {
9445 var row = this.selection.getCursor().row;
9446 row = this.getRowFoldStart(row);
9447 var range = this.$toggleFoldWidget(row, {});
9448
9449 if (range)
9450 return;
9451 var data = this.getParentFoldRangeData(row, true);
9452 range = data.range || data.firstRange;
9453
9454 if (range) {
9455 row = range.start.row;
9456 var fold = this.getFoldAt(row, this.getLine(row).length, 1);
9457
9458 if (fold) {
9459 this.removeFold(fold);
9460 } else {
9461 this.addFold("...", range);
9462 }
9463 }
9464 };
9465
9466 this.updateFoldWidgets = function(delta) {
9467 var firstRow = delta.start.row;
9468 var len = delta.end.row - firstRow;
9469
9470 if (len === 0) {
9471 this.foldWidgets[firstRow] = null;
9472 } else if (delta.action == 'remove') {
9473 this.foldWidgets.splice(firstRow, len + 1, null);
9474 } else {
9475 var args = Array(len + 1);
9476 args.unshift(firstRow, 1);
9477 this.foldWidgets.splice.apply(this.foldWidgets, args);
9478 }
9479 };
9480 this.tokenizerUpdateFoldWidgets = function(e) {
9481 var rows = e.data;
9482 if (rows.first != rows.last) {
9483 if (this.foldWidgets.length > rows.first)
9484 this.foldWidgets.splice(rows.first, this.foldWidgets.length);
9485 }
9486 };
9487 }
9488
9489 exports.Folding = Folding;
9490
9491 });
9492
9493 define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"], function(require, exports, module) {
9494 "use strict";
9495
9496 var TokenIterator = require("../token_iterator").TokenIterator;
9497 var Range = require("../range").Range;
9498
9499
9500 function BracketMatch() {
9501
9502 this.findMatchingBracket = function(position, chr) {
9503 if (position.column == 0) return null;
9504
9505 var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);
9506 if (charBeforeCursor == "") return null;
9507
9508 var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
9509 if (!match)
9510 return null;
9511
9512 if (match[1])
9513 return this.$findClosingBracket(match[1], position);
9514 else
9515 return this.$findOpeningBracket(match[2], position);
9516 };
9517
9518 this.getBracketRange = function(pos) {
9519 var line = this.getLine(pos.row);
9520 var before = true, range;
9521
9522 var chr = line.charAt(pos.column-1);
9523 var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9524 if (!match) {
9525 chr = line.charAt(pos.column);
9526 pos = {row: pos.row, column: pos.column + 1};
9527 match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9528 before = false;
9529 }
9530 if (!match)
9531 return null;
9532
9533 if (match[1]) {
9534 var bracketPos = this.$findClosingBracket(match[1], pos);
9535 if (!bracketPos)
9536 return null;
9537 range = Range.fromPoints(pos, bracketPos);
9538 if (!before) {
9539 range.end.column++;
9540 range.start.column--;
9541 }
9542 range.cursor = range.end;
9543 } else {
9544 var bracketPos = this.$findOpeningBracket(match[2], pos);
9545 if (!bracketPos)
9546 return null;
9547 range = Range.fromPoints(bracketPos, pos);
9548 if (!before) {
9549 range.start.column++;
9550 range.end.column--;
9551 }
9552 range.cursor = range.start;
9553 }
9554
9555 return range;
9556 };
9557
9558 this.$brackets = {
9559 ")": "(",
9560 "(": ")",
9561 "]": "[",
9562 "[": "]",
9563 "{": "}",
9564 "}": "{"
9565 };
9566
9567 this.$findOpeningBracket = function(bracket, position, typeRe) {
9568 var openBracket = this.$brackets[bracket];
9569 var depth = 1;
9570
9571 var iterator = new TokenIterator(this, position.row, position.column);
9572 var token = iterator.getCurrentToken();
9573 if (!token)
9574 token = iterator.stepForward();
9575 if (!token)
9576 return;
9577
9578 if (!typeRe){
9579 typeRe = new RegExp(
9580 "(\\.?" +
9581 token.type.replace(".", "\\.").replace("rparen", ".paren")
9582 .replace(/\b(?:end)\b/, "(?:start|begin|end)")
9583 + ")+"
9584 );
9585 }
9586 var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
9587 var value = token.value;
9588
9589 while (true) {
9590
9591 while (valueIndex >= 0) {
9592 var chr = value.charAt(valueIndex);
9593 if (chr == openBracket) {
9594 depth -= 1;
9595 if (depth == 0) {
9596 return {row: iterator.getCurrentTokenRow(),
9597 column: valueIndex + iterator.getCurrentTokenColumn()};
9598 }
9599 }
9600 else if (chr == bracket) {
9601 depth += 1;
9602 }
9603 valueIndex -= 1;
9604 }
9605 do {
9606 token = iterator.stepBackward();
9607 } while (token && !typeRe.test(token.type));
9608
9609 if (token == null)
9610 break;
9611
9612 value = token.value;
9613 valueIndex = value.length - 1;
9614 }
9615
9616 return null;
9617 };
9618
9619 this.$findClosingBracket = function(bracket, position, typeRe) {
9620 var closingBracket = this.$brackets[bracket];
9621 var depth = 1;
9622
9623 var iterator = new TokenIterator(this, position.row, position.column);
9624 var token = iterator.getCurrentToken();
9625 if (!token)
9626 token = iterator.stepForward();
9627 if (!token)
9628 return;
9629
9630 if (!typeRe){
9631 typeRe = new RegExp(
9632 "(\\.?" +
9633 token.type.replace(".", "\\.").replace("lparen", ".paren")
9634 .replace(/\b(?:start|begin)\b/, "(?:start|begin|end)")
9635 + ")+"
9636 );
9637 }
9638 var valueIndex = position.column - iterator.getCurrentTokenColumn();
9639
9640 while (true) {
9641
9642 var value = token.value;
9643 var valueLength = value.length;
9644 while (valueIndex < valueLength) {
9645 var chr = value.charAt(valueIndex);
9646 if (chr == closingBracket) {
9647 depth -= 1;
9648 if (depth == 0) {
9649 return {row: iterator.getCurrentTokenRow(),
9650 column: valueIndex + iterator.getCurrentTokenColumn()};
9651 }
9652 }
9653 else if (chr == bracket) {
9654 depth += 1;
9655 }
9656 valueIndex += 1;
9657 }
9658 do {
9659 token = iterator.stepForward();
9660 } while (token && !typeRe.test(token.type));
9661
9662 if (token == null)
9663 break;
9664
9665 valueIndex = 0;
9666 }
9667
9668 return null;
9669 };
9670 }
9671 exports.BracketMatch = BracketMatch;
9672
9673 });
9674
9675 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(require, exports, module) {
9676 "use strict";
9677
9678 var oop = require("./lib/oop");
9679 var lang = require("./lib/lang");
9680 var BidiHandler = require("./bidihandler").BidiHandler;
9681 var config = require("./config");
9682 var EventEmitter = require("./lib/event_emitter").EventEmitter;
9683 var Selection = require("./selection").Selection;
9684 var TextMode = require("./mode/text").Mode;
9685 var Range = require("./range").Range;
9686 var Document = require("./document").Document;
9687 var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
9688 var SearchHighlight = require("./search_highlight").SearchHighlight;
9689
9690 var EditSession = function(text, mode) {
9691 this.$breakpoints = [];
9692 this.$decorations = [];
9693 this.$frontMarkers = {};
9694 this.$backMarkers = {};
9695 this.$markerId = 1;
9696 this.$undoSelect = true;
9697
9698 this.$foldData = [];
9699 this.id = "session" + (++EditSession.$uid);
9700 this.$foldData.toString = function() {
9701 return this.join("\n");
9702 };
9703 this.on("changeFold", this.onChangeFold.bind(this));
9704 this.$onChange = this.onChange.bind(this);
9705
9706 if (typeof text != "object" || !text.getLine)
9707 text = new Document(text);
9708
9709 this.$bidiHandler = new BidiHandler(this);
9710 this.setDocument(text);
9711 this.selection = new Selection(this);
9712
9713 config.resetOptions(this);
9714 this.setMode(mode);
9715 config._signal("session", this);
9716 };
9717
9718
9719 EditSession.$uid = 0;
9720
9721 (function() {
9722
9723 oop.implement(this, EventEmitter);
9724 this.setDocument = function(doc) {
9725 if (this.doc)
9726 this.doc.removeListener("change", this.$onChange);
9727
9728 this.doc = doc;
9729 doc.on("change", this.$onChange);
9730
9731 if (this.bgTokenizer)
9732 this.bgTokenizer.setDocument(this.getDocument());
9733
9734 this.resetCaches();
9735 };
9736 this.getDocument = function() {
9737 return this.doc;
9738 };
9739 this.$resetRowCache = function(docRow) {
9740 if (!docRow) {
9741 this.$docRowCache = [];
9742 this.$screenRowCache = [];
9743 return;
9744 }
9745 var l = this.$docRowCache.length;
9746 var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;
9747 if (l > i) {
9748 this.$docRowCache.splice(i, l);
9749 this.$screenRowCache.splice(i, l);
9750 }
9751 };
9752
9753 this.$getRowCacheIndex = function(cacheArray, val) {
9754 var low = 0;
9755 var hi = cacheArray.length - 1;
9756
9757 while (low <= hi) {
9758 var mid = (low + hi) >> 1;
9759 var c = cacheArray[mid];
9760
9761 if (val > c)
9762 low = mid + 1;
9763 else if (val < c)
9764 hi = mid - 1;
9765 else
9766 return mid;
9767 }
9768
9769 return low -1;
9770 };
9771
9772 this.resetCaches = function() {
9773 this.$modified = true;
9774 this.$wrapData = [];
9775 this.$rowLengthCache = [];
9776 this.$resetRowCache(0);
9777 if (this.bgTokenizer)
9778 this.bgTokenizer.start(0);
9779 };
9780
9781 this.onChangeFold = function(e) {
9782 var fold = e.data;
9783 this.$resetRowCache(fold.start.row);
9784 };
9785
9786 this.onChange = function(delta) {
9787 this.$modified = true;
9788 this.$bidiHandler.onChange(delta);
9789 this.$resetRowCache(delta.start.row);
9790
9791 var removedFolds = this.$updateInternalDataOnChange(delta);
9792 if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
9793 this.$deltasDoc.push(delta);
9794 if (removedFolds && removedFolds.length != 0) {
9795 this.$deltasFold.push({
9796 action: "removeFolds",
9797 folds: removedFolds
9798 });
9799 }
9800
9801 this.$informUndoManager.schedule();
9802 }
9803
9804 this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta);
9805 this._signal("change", delta);
9806 };
9807 this.setValue = function(text) {
9808 this.doc.setValue(text);
9809 this.selection.moveTo(0, 0);
9810
9811 this.$resetRowCache(0);
9812 this.$deltas = [];
9813 this.$deltasDoc = [];
9814 this.$deltasFold = [];
9815 this.setUndoManager(this.$undoManager);
9816 this.getUndoManager().reset();
9817 };
9818 this.getValue =
9819 this.toString = function() {
9820 return this.doc.getValue();
9821 };
9822 this.getSelection = function() {
9823 return this.selection;
9824 };
9825 this.getState = function(row) {
9826 return this.bgTokenizer.getState(row);
9827 };
9828 this.getTokens = function(row) {
9829 return this.bgTokenizer.getTokens(row);
9830 };
9831 this.getTokenAt = function(row, column) {
9832 var tokens = this.bgTokenizer.getTokens(row);
9833 var token, c = 0;
9834 if (column == null) {
9835 var i = tokens.length - 1;
9836 c = this.getLine(row).length;
9837 } else {
9838 for (var i = 0; i < tokens.length; i++) {
9839 c += tokens[i].value.length;
9840 if (c >= column)
9841 break;
9842 }
9843 }
9844 token = tokens[i];
9845 if (!token)
9846 return null;
9847 token.index = i;
9848 token.start = c - token.value.length;
9849 return token;
9850 };
9851 this.setUndoManager = function(undoManager) {
9852 this.$undoManager = undoManager;
9853 this.$deltas = [];
9854 this.$deltasDoc = [];
9855 this.$deltasFold = [];
9856
9857 if (this.$informUndoManager)
9858 this.$informUndoManager.cancel();
9859
9860 if (undoManager) {
9861 var self = this;
9862
9863 this.$syncInformUndoManager = function() {
9864 self.$informUndoManager.cancel();
9865
9866 if (self.$deltasFold.length) {
9867 self.$deltas.push({
9868 group: "fold",
9869 deltas: self.$deltasFold
9870 });
9871 self.$deltasFold = [];
9872 }
9873
9874 if (self.$deltasDoc.length) {
9875 self.$deltas.push({
9876 group: "doc",
9877 deltas: self.$deltasDoc
9878 });
9879 self.$deltasDoc = [];
9880 }
9881
9882 if (self.$deltas.length > 0) {
9883 undoManager.execute({
9884 action: "aceupdate",
9885 args: [self.$deltas, self],
9886 merge: self.mergeUndoDeltas
9887 });
9888 }
9889 self.mergeUndoDeltas = false;
9890 self.$deltas = [];
9891 };
9892 this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);
9893 }
9894 };
9895 this.markUndoGroup = function() {
9896 if (this.$syncInformUndoManager)
9897 this.$syncInformUndoManager();
9898 };
9899
9900 this.$defaultUndoManager = {
9901 undo: function() {},
9902 redo: function() {},
9903 reset: function() {}
9904 };
9905 this.getUndoManager = function() {
9906 return this.$undoManager || this.$defaultUndoManager;
9907 };
9908 this.getTabString = function() {
9909 if (this.getUseSoftTabs()) {
9910 return lang.stringRepeat(" ", this.getTabSize());
9911 } else {
9912 return "\t";
9913 }
9914 };
9915 this.setUseSoftTabs = function(val) {
9916 this.setOption("useSoftTabs", val);
9917 };
9918 this.getUseSoftTabs = function() {
9919 return this.$useSoftTabs && !this.$mode.$indentWithTabs;
9920 };
9921 this.setTabSize = function(tabSize) {
9922 this.setOption("tabSize", tabSize);
9923 };
9924 this.getTabSize = function() {
9925 return this.$tabSize;
9926 };
9927 this.isTabStop = function(position) {
9928 return this.$useSoftTabs && (position.column % this.$tabSize === 0);
9929 };
9930 this.setNavigateWithinSoftTabs = function (navigateWithinSoftTabs) {
9931 this.setOption("navigateWithinSoftTabs", navigateWithinSoftTabs);
9932 };
9933 this.getNavigateWithinSoftTabs = function() {
9934 return this.$navigateWithinSoftTabs;
9935 };
9936
9937 this.$overwrite = false;
9938 this.setOverwrite = function(overwrite) {
9939 this.setOption("overwrite", overwrite);
9940 };
9941 this.getOverwrite = function() {
9942 return this.$overwrite;
9943 };
9944 this.toggleOverwrite = function() {
9945 this.setOverwrite(!this.$overwrite);
9946 };
9947 this.addGutterDecoration = function(row, className) {
9948 if (!this.$decorations[row])
9949 this.$decorations[row] = "";
9950 this.$decorations[row] += " " + className;
9951 this._signal("changeBreakpoint", {});
9952 };
9953 this.removeGutterDecoration = function(row, className) {
9954 this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
9955 this._signal("changeBreakpoint", {});
9956 };
9957 this.getBreakpoints = function() {
9958 return this.$breakpoints;
9959 };
9960 this.setBreakpoints = function(rows) {
9961 this.$breakpoints = [];
9962 for (var i=0; i<rows.length; i++) {
9963 this.$breakpoints[rows[i]] = "ace_breakpoint";
9964 }
9965 this._signal("changeBreakpoint", {});
9966 };
9967 this.clearBreakpoints = function() {
9968 this.$breakpoints = [];
9969 this._signal("changeBreakpoint", {});
9970 };
9971 this.setBreakpoint = function(row, className) {
9972 if (className === undefined)
9973 className = "ace_breakpoint";
9974 if (className)
9975 this.$breakpoints[row] = className;
9976 else
9977 delete this.$breakpoints[row];
9978 this._signal("changeBreakpoint", {});
9979 };
9980 this.clearBreakpoint = function(row) {
9981 delete this.$breakpoints[row];
9982 this._signal("changeBreakpoint", {});
9983 };
9984 this.addMarker = function(range, clazz, type, inFront) {
9985 var id = this.$markerId++;
9986
9987 var marker = {
9988 range : range,
9989 type : type || "line",
9990 renderer: typeof type == "function" ? type : null,
9991 clazz : clazz,
9992 inFront: !!inFront,
9993 id: id
9994 };
9995
9996 if (inFront) {
9997 this.$frontMarkers[id] = marker;
9998 this._signal("changeFrontMarker");
9999 } else {
10000 this.$backMarkers[id] = marker;
10001 this._signal("changeBackMarker");
10002 }
10003
10004 return id;
10005 };
10006 this.addDynamicMarker = function(marker, inFront) {
10007 if (!marker.update)
10008 return;
10009 var id = this.$markerId++;
10010 marker.id = id;
10011 marker.inFront = !!inFront;
10012
10013 if (inFront) {
10014 this.$frontMarkers[id] = marker;
10015 this._signal("changeFrontMarker");
10016 } else {
10017 this.$backMarkers[id] = marker;
10018 this._signal("changeBackMarker");
10019 }
10020
10021 return marker;
10022 };
10023 this.removeMarker = function(markerId) {
10024 var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
10025 if (!marker)
10026 return;
10027
10028 var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
10029 if (marker) {
10030 delete (markers[markerId]);
10031 this._signal(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
10032 }
10033 };
10034 this.getMarkers = function(inFront) {
10035 return inFront ? this.$frontMarkers : this.$backMarkers;
10036 };
10037
10038 this.highlight = function(re) {
10039 if (!this.$searchHighlight) {
10040 var highlight = new SearchHighlight(null, "ace_selected-word", "text");
10041 this.$searchHighlight = this.addDynamicMarker(highlight);
10042 }
10043 this.$searchHighlight.setRegexp(re);
10044 };
10045 this.highlightLines = function(startRow, endRow, clazz, inFront) {
10046 if (typeof endRow != "number") {
10047 clazz = endRow;
10048 endRow = startRow;
10049 }
10050 if (!clazz)
10051 clazz = "ace_step";
10052
10053 var range = new Range(startRow, 0, endRow, Infinity);
10054 range.id = this.addMarker(range, clazz, "fullLine", inFront);
10055 return range;
10056 };
10057 this.setAnnotations = function(annotations) {
10058 this.$annotations = annotations;
10059 this._signal("changeAnnotation", {});
10060 };
10061 this.getAnnotations = function() {
10062 return this.$annotations || [];
10063 };
10064 this.clearAnnotations = function() {
10065 this.setAnnotations([]);
10066 };
10067 this.$detectNewLine = function(text) {
10068 var match = text.match(/^.*?(\r?\n)/m);
10069 if (match) {
10070 this.$autoNewLine = match[1];
10071 } else {
10072 this.$autoNewLine = "\n";
10073 }
10074 };
10075 this.getWordRange = function(row, column) {
10076 var line = this.getLine(row);
10077
10078 var inToken = false;
10079 if (column > 0)
10080 inToken = !!line.charAt(column - 1).match(this.tokenRe);
10081
10082 if (!inToken)
10083 inToken = !!line.charAt(column).match(this.tokenRe);
10084
10085 if (inToken)
10086 var re = this.tokenRe;
10087 else if (/^\s+$/.test(line.slice(column-1, column+1)))
10088 var re = /\s/;
10089 else
10090 var re = this.nonTokenRe;
10091
10092 var start = column;
10093 if (start > 0) {
10094 do {
10095 start--;
10096 }
10097 while (start >= 0 && line.charAt(start).match(re));
10098 start++;
10099 }
10100
10101 var end = column;
10102 while (end < line.length && line.charAt(end).match(re)) {
10103 end++;
10104 }
10105
10106 return new Range(row, start, row, end);
10107 };
10108 this.getAWordRange = function(row, column) {
10109 var wordRange = this.getWordRange(row, column);
10110 var line = this.getLine(wordRange.end.row);
10111
10112 while (line.charAt(wordRange.end.column).match(/[ \t]/)) {
10113 wordRange.end.column += 1;
10114 }
10115 return wordRange;
10116 };
10117 this.setNewLineMode = function(newLineMode) {
10118 this.doc.setNewLineMode(newLineMode);
10119 };
10120 this.getNewLineMode = function() {
10121 return this.doc.getNewLineMode();
10122 };
10123 this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); };
10124 this.getUseWorker = function() { return this.$useWorker; };
10125 this.onReloadTokenizer = function(e) {
10126 var rows = e.data;
10127 this.bgTokenizer.start(rows.first);
10128 this._signal("tokenizerUpdate", e);
10129 };
10130
10131 this.$modes = {};
10132 this.$mode = null;
10133 this.$modeId = null;
10134 this.setMode = function(mode, cb) {
10135 if (mode && typeof mode === "object") {
10136 if (mode.getTokenizer)
10137 return this.$onChangeMode(mode);
10138 var options = mode;
10139 var path = options.path;
10140 } else {
10141 path = mode || "ace/mode/text";
10142 }
10143 if (!this.$modes["ace/mode/text"])
10144 this.$modes["ace/mode/text"] = new TextMode();
10145
10146 if (this.$modes[path] && !options) {
10147 this.$onChangeMode(this.$modes[path]);
10148 cb && cb();
10149 return;
10150 }
10151 this.$modeId = path;
10152 config.loadModule(["mode", path], function(m) {
10153 if (this.$modeId !== path)
10154 return cb && cb();
10155 if (this.$modes[path] && !options) {
10156 this.$onChangeMode(this.$modes[path]);
10157 } else if (m && m.Mode) {
10158 m = new m.Mode(options);
10159 if (!options) {
10160 this.$modes[path] = m;
10161 m.$id = path;
10162 }
10163 this.$onChangeMode(m);
10164 }
10165 cb && cb();
10166 }.bind(this));
10167 if (!this.$mode)
10168 this.$onChangeMode(this.$modes["ace/mode/text"], true);
10169 };
10170
10171 this.$onChangeMode = function(mode, $isPlaceholder) {
10172 if (!$isPlaceholder)
10173 this.$modeId = mode.$id;
10174 if (this.$mode === mode)
10175 return;
10176
10177 this.$mode = mode;
10178
10179 this.$stopWorker();
10180
10181 if (this.$useWorker)
10182 this.$startWorker();
10183
10184 var tokenizer = mode.getTokenizer();
10185
10186 if(tokenizer.addEventListener !== undefined) {
10187 var onReloadTokenizer = this.onReloadTokenizer.bind(this);
10188 tokenizer.addEventListener("update", onReloadTokenizer);
10189 }
10190
10191 if (!this.bgTokenizer) {
10192 this.bgTokenizer = new BackgroundTokenizer(tokenizer);
10193 var _self = this;
10194 this.bgTokenizer.addEventListener("update", function(e) {
10195 _self._signal("tokenizerUpdate", e);
10196 });
10197 } else {
10198 this.bgTokenizer.setTokenizer(tokenizer);
10199 }
10200
10201 this.bgTokenizer.setDocument(this.getDocument());
10202
10203 this.tokenRe = mode.tokenRe;
10204 this.nonTokenRe = mode.nonTokenRe;
10205
10206
10207 if (!$isPlaceholder) {
10208 if (mode.attachToSession)
10209 mode.attachToSession(this);
10210 this.$options.wrapMethod.set.call(this, this.$wrapMethod);
10211 this.$setFolding(mode.foldingRules);
10212 this.bgTokenizer.start(0);
10213 this._emit("changeMode");
10214 }
10215 };
10216
10217 this.$stopWorker = function() {
10218 if (this.$worker) {
10219 this.$worker.terminate();
10220 this.$worker = null;
10221 }
10222 };
10223
10224 this.$startWorker = function() {
10225 try {
10226 this.$worker = this.$mode.createWorker(this);
10227 } catch (e) {
10228 config.warn("Could not load worker", e);
10229 this.$worker = null;
10230 }
10231 };
10232 this.getMode = function() {
10233 return this.$mode;
10234 };
10235
10236 this.$scrollTop = 0;
10237 this.setScrollTop = function(scrollTop) {
10238 if (this.$scrollTop === scrollTop || isNaN(scrollTop))
10239 return;
10240
10241 this.$scrollTop = scrollTop;
10242 this._signal("changeScrollTop", scrollTop);
10243 };
10244 this.getScrollTop = function() {
10245 return this.$scrollTop;
10246 };
10247
10248 this.$scrollLeft = 0;
10249 this.setScrollLeft = function(scrollLeft) {
10250 if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
10251 return;
10252
10253 this.$scrollLeft = scrollLeft;
10254 this._signal("changeScrollLeft", scrollLeft);
10255 };
10256 this.getScrollLeft = function() {
10257 return this.$scrollLeft;
10258 };
10259 this.getScreenWidth = function() {
10260 this.$computeWidth();
10261 if (this.lineWidgets)
10262 return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);
10263 return this.screenWidth;
10264 };
10265
10266 this.getLineWidgetMaxWidth = function() {
10267 if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth;
10268 var width = 0;
10269 this.lineWidgets.forEach(function(w) {
10270 if (w && w.screenWidth > width)
10271 width = w.screenWidth;
10272 });
10273 return this.lineWidgetWidth = width;
10274 };
10275
10276 this.$computeWidth = function(force) {
10277 if (this.$modified || force) {
10278 this.$modified = false;
10279
10280 if (this.$useWrapMode)
10281 return this.screenWidth = this.$wrapLimit;
10282
10283 var lines = this.doc.getAllLines();
10284 var cache = this.$rowLengthCache;
10285 var longestScreenLine = 0;
10286 var foldIndex = 0;
10287 var foldLine = this.$foldData[foldIndex];
10288 var foldStart = foldLine ? foldLine.start.row : Infinity;
10289 var len = lines.length;
10290
10291 for (var i = 0; i < len; i++) {
10292 if (i > foldStart) {
10293 i = foldLine.end.row + 1;
10294 if (i >= len)
10295 break;
10296 foldLine = this.$foldData[foldIndex++];
10297 foldStart = foldLine ? foldLine.start.row : Infinity;
10298 }
10299
10300 if (cache[i] == null)
10301 cache[i] = this.$getStringScreenWidth(lines[i])[0];
10302
10303 if (cache[i] > longestScreenLine)
10304 longestScreenLine = cache[i];
10305 }
10306 this.screenWidth = longestScreenLine;
10307 }
10308 };
10309 this.getLine = function(row) {
10310 return this.doc.getLine(row);
10311 };
10312 this.getLines = function(firstRow, lastRow) {
10313 return this.doc.getLines(firstRow, lastRow);
10314 };
10315 this.getLength = function() {
10316 return this.doc.getLength();
10317 };
10318 this.getTextRange = function(range) {
10319 return this.doc.getTextRange(range || this.selection.getRange());
10320 };
10321 this.insert = function(position, text) {
10322 return this.doc.insert(position, text);
10323 };
10324 this.remove = function(range) {
10325 return this.doc.remove(range);
10326 };
10327 this.removeFullLines = function(firstRow, lastRow){
10328 return this.doc.removeFullLines(firstRow, lastRow);
10329 };
10330 this.undoChanges = function(deltas, dontSelect) {
10331 if (!deltas.length)
10332 return;
10333
10334 this.$fromUndo = true;
10335 var lastUndoRange = null;
10336 for (var i = deltas.length - 1; i != -1; i--) {
10337 var delta = deltas[i];
10338 if (delta.group == "doc") {
10339 this.doc.revertDeltas(delta.deltas);
10340 lastUndoRange =
10341 this.$getUndoSelection(delta.deltas, true, lastUndoRange);
10342 } else {
10343 delta.deltas.forEach(function(foldDelta) {
10344 this.addFolds(foldDelta.folds);
10345 }, this);
10346 }
10347 }
10348 this.$fromUndo = false;
10349 lastUndoRange &&
10350 this.$undoSelect &&
10351 !dontSelect &&
10352 this.selection.setSelectionRange(lastUndoRange);
10353 return lastUndoRange;
10354 };
10355 this.redoChanges = function(deltas, dontSelect) {
10356 if (!deltas.length)
10357 return;
10358
10359 this.$fromUndo = true;
10360 var lastUndoRange = null;
10361 for (var i = 0; i < deltas.length; i++) {
10362 var delta = deltas[i];
10363 if (delta.group == "doc") {
10364 this.doc.applyDeltas(delta.deltas);
10365 lastUndoRange =
10366 this.$getUndoSelection(delta.deltas, false, lastUndoRange);
10367 }
10368 }
10369 this.$fromUndo = false;
10370 lastUndoRange &&
10371 this.$undoSelect &&
10372 !dontSelect &&
10373 this.selection.setSelectionRange(lastUndoRange);
10374 return lastUndoRange;
10375 };
10376 this.setUndoSelect = function(enable) {
10377 this.$undoSelect = enable;
10378 };
10379
10380 this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
10381 function isInsert(delta) {
10382 return isUndo ? delta.action !== "insert" : delta.action === "insert";
10383 }
10384
10385 var delta = deltas[0];
10386 var range, point;
10387 var lastDeltaIsInsert = false;
10388 if (isInsert(delta)) {
10389 range = Range.fromPoints(delta.start, delta.end);
10390 lastDeltaIsInsert = true;
10391 } else {
10392 range = Range.fromPoints(delta.start, delta.start);
10393 lastDeltaIsInsert = false;
10394 }
10395
10396 for (var i = 1; i < deltas.length; i++) {
10397 delta = deltas[i];
10398 if (isInsert(delta)) {
10399 point = delta.start;
10400 if (range.compare(point.row, point.column) == -1) {
10401 range.setStart(point);
10402 }
10403 point = delta.end;
10404 if (range.compare(point.row, point.column) == 1) {
10405 range.setEnd(point);
10406 }
10407 lastDeltaIsInsert = true;
10408 } else {
10409 point = delta.start;
10410 if (range.compare(point.row, point.column) == -1) {
10411 range = Range.fromPoints(delta.start, delta.start);
10412 }
10413 lastDeltaIsInsert = false;
10414 }
10415 }
10416 if (lastUndoRange != null) {
10417 if (Range.comparePoints(lastUndoRange.start, range.start) === 0) {
10418 lastUndoRange.start.column += range.end.column - range.start.column;
10419 lastUndoRange.end.column += range.end.column - range.start.column;
10420 }
10421
10422 var cmp = lastUndoRange.compareRange(range);
10423 if (cmp == 1) {
10424 range.setStart(lastUndoRange.start);
10425 } else if (cmp == -1) {
10426 range.setEnd(lastUndoRange.end);
10427 }
10428 }
10429
10430 return range;
10431 };
10432 this.replace = function(range, text) {
10433 return this.doc.replace(range, text);
10434 };
10435 this.moveText = function(fromRange, toPosition, copy) {
10436 var text = this.getTextRange(fromRange);
10437 var folds = this.getFoldsInRange(fromRange);
10438
10439 var toRange = Range.fromPoints(toPosition, toPosition);
10440 if (!copy) {
10441 this.remove(fromRange);
10442 var rowDiff = fromRange.start.row - fromRange.end.row;
10443 var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
10444 if (collDiff) {
10445 if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
10446 toRange.start.column += collDiff;
10447 if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
10448 toRange.end.column += collDiff;
10449 }
10450 if (rowDiff && toRange.start.row >= fromRange.end.row) {
10451 toRange.start.row += rowDiff;
10452 toRange.end.row += rowDiff;
10453 }
10454 }
10455
10456 toRange.end = this.insert(toRange.start, text);
10457 if (folds.length) {
10458 var oldStart = fromRange.start;
10459 var newStart = toRange.start;
10460 var rowDiff = newStart.row - oldStart.row;
10461 var collDiff = newStart.column - oldStart.column;
10462 this.addFolds(folds.map(function(x) {
10463 x = x.clone();
10464 if (x.start.row == oldStart.row)
10465 x.start.column += collDiff;
10466 if (x.end.row == oldStart.row)
10467 x.end.column += collDiff;
10468 x.start.row += rowDiff;
10469 x.end.row += rowDiff;
10470 return x;
10471 }));
10472 }
10473
10474 return toRange;
10475 };
10476 this.indentRows = function(startRow, endRow, indentString) {
10477 indentString = indentString.replace(/\t/g, this.getTabString());
10478 for (var row=startRow; row<=endRow; row++)
10479 this.doc.insertInLine({row: row, column: 0}, indentString);
10480 };
10481 this.outdentRows = function (range) {
10482 var rowRange = range.collapseRows();
10483 var deleteRange = new Range(0, 0, 0, 0);
10484 var size = this.getTabSize();
10485
10486 for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
10487 var line = this.getLine(i);
10488
10489 deleteRange.start.row = i;
10490 deleteRange.end.row = i;
10491 for (var j = 0; j < size; ++j)
10492 if (line.charAt(j) != ' ')
10493 break;
10494 if (j < size && line.charAt(j) == '\t') {
10495 deleteRange.start.column = j;
10496 deleteRange.end.column = j + 1;
10497 } else {
10498 deleteRange.start.column = 0;
10499 deleteRange.end.column = j;
10500 }
10501 this.remove(deleteRange);
10502 }
10503 };
10504
10505 this.$moveLines = function(firstRow, lastRow, dir) {
10506 firstRow = this.getRowFoldStart(firstRow);
10507 lastRow = this.getRowFoldEnd(lastRow);
10508 if (dir < 0) {
10509 var row = this.getRowFoldStart(firstRow + dir);
10510 if (row < 0) return 0;
10511 var diff = row-firstRow;
10512 } else if (dir > 0) {
10513 var row = this.getRowFoldEnd(lastRow + dir);
10514 if (row > this.doc.getLength()-1) return 0;
10515 var diff = row-lastRow;
10516 } else {
10517 firstRow = this.$clipRowToDocument(firstRow);
10518 lastRow = this.$clipRowToDocument(lastRow);
10519 var diff = lastRow - firstRow + 1;
10520 }
10521
10522 var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
10523 var folds = this.getFoldsInRange(range).map(function(x){
10524 x = x.clone();
10525 x.start.row += diff;
10526 x.end.row += diff;
10527 return x;
10528 });
10529
10530 var lines = dir == 0
10531 ? this.doc.getLines(firstRow, lastRow)
10532 : this.doc.removeFullLines(firstRow, lastRow);
10533 this.doc.insertFullLines(firstRow+diff, lines);
10534 folds.length && this.addFolds(folds);
10535 return diff;
10536 };
10537 this.moveLinesUp = function(firstRow, lastRow) {
10538 return this.$moveLines(firstRow, lastRow, -1);
10539 };
10540 this.moveLinesDown = function(firstRow, lastRow) {
10541 return this.$moveLines(firstRow, lastRow, 1);
10542 };
10543 this.duplicateLines = function(firstRow, lastRow) {
10544 return this.$moveLines(firstRow, lastRow, 0);
10545 };
10546
10547
10548 this.$clipRowToDocument = function(row) {
10549 return Math.max(0, Math.min(row, this.doc.getLength()-1));
10550 };
10551
10552 this.$clipColumnToRow = function(row, column) {
10553 if (column < 0)
10554 return 0;
10555 return Math.min(this.doc.getLine(row).length, column);
10556 };
10557
10558
10559 this.$clipPositionToDocument = function(row, column) {
10560 column = Math.max(0, column);
10561
10562 if (row < 0) {
10563 row = 0;
10564 column = 0;
10565 } else {
10566 var len = this.doc.getLength();
10567 if (row >= len) {
10568 row = len - 1;
10569 column = this.doc.getLine(len-1).length;
10570 } else {
10571 column = Math.min(this.doc.getLine(row).length, column);
10572 }
10573 }
10574
10575 return {
10576 row: row,
10577 column: column
10578 };
10579 };
10580
10581 this.$clipRangeToDocument = function(range) {
10582 if (range.start.row < 0) {
10583 range.start.row = 0;
10584 range.start.column = 0;
10585 } else {
10586 range.start.column = this.$clipColumnToRow(
10587 range.start.row,
10588 range.start.column
10589 );
10590 }
10591
10592 var len = this.doc.getLength() - 1;
10593 if (range.end.row > len) {
10594 range.end.row = len;
10595 range.end.column = this.doc.getLine(len).length;
10596 } else {
10597 range.end.column = this.$clipColumnToRow(
10598 range.end.row,
10599 range.end.column
10600 );
10601 }
10602 return range;
10603 };
10604 this.$wrapLimit = 80;
10605 this.$useWrapMode = false;
10606 this.$wrapLimitRange = {
10607 min : null,
10608 max : null
10609 };
10610 this.setUseWrapMode = function(useWrapMode) {
10611 if (useWrapMode != this.$useWrapMode) {
10612 this.$useWrapMode = useWrapMode;
10613 this.$modified = true;
10614 this.$resetRowCache(0);
10615 if (useWrapMode) {
10616 var len = this.getLength();
10617 this.$wrapData = Array(len);
10618 this.$updateWrapData(0, len - 1);
10619 }
10620
10621 this._signal("changeWrapMode");
10622 }
10623 };
10624 this.getUseWrapMode = function() {
10625 return this.$useWrapMode;
10626 };
10627 this.setWrapLimitRange = function(min, max) {
10628 if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
10629 this.$wrapLimitRange = { min: min, max: max };
10630 this.$modified = true;
10631 this.$bidiHandler.markAsDirty();
10632 if (this.$useWrapMode)
10633 this._signal("changeWrapMode");
10634 }
10635 };
10636 this.adjustWrapLimit = function(desiredLimit, $printMargin) {
10637 var limits = this.$wrapLimitRange;
10638 if (limits.max < 0)
10639 limits = {min: $printMargin, max: $printMargin};
10640 var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max);
10641 if (wrapLimit != this.$wrapLimit && wrapLimit > 1) {
10642 this.$wrapLimit = wrapLimit;
10643 this.$modified = true;
10644 if (this.$useWrapMode) {
10645 this.$updateWrapData(0, this.getLength() - 1);
10646 this.$resetRowCache(0);
10647 this._signal("changeWrapLimit");
10648 }
10649 return true;
10650 }
10651 return false;
10652 };
10653
10654 this.$constrainWrapLimit = function(wrapLimit, min, max) {
10655 if (min)
10656 wrapLimit = Math.max(min, wrapLimit);
10657
10658 if (max)
10659 wrapLimit = Math.min(max, wrapLimit);
10660
10661 return wrapLimit;
10662 };
10663 this.getWrapLimit = function() {
10664 return this.$wrapLimit;
10665 };
10666 this.setWrapLimit = function (limit) {
10667 this.setWrapLimitRange(limit, limit);
10668 };
10669 this.getWrapLimitRange = function() {
10670 return {
10671 min : this.$wrapLimitRange.min,
10672 max : this.$wrapLimitRange.max
10673 };
10674 };
10675
10676 this.$updateInternalDataOnChange = function(delta) {
10677 var useWrapMode = this.$useWrapMode;
10678 var action = delta.action;
10679 var start = delta.start;
10680 var end = delta.end;
10681 var firstRow = start.row;
10682 var lastRow = end.row;
10683 var len = lastRow - firstRow;
10684 var removedFolds = null;
10685
10686 this.$updating = true;
10687 if (len != 0) {
10688 if (action === "remove") {
10689 this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len);
10690
10691 var foldLines = this.$foldData;
10692 removedFolds = this.getFoldsInRange(delta);
10693 this.removeFolds(removedFolds);
10694
10695 var foldLine = this.getFoldLine(end.row);
10696 var idx = 0;
10697 if (foldLine) {
10698 foldLine.addRemoveChars(end.row, end.column, start.column - end.column);
10699 foldLine.shiftRow(-len);
10700
10701 var foldLineBefore = this.getFoldLine(firstRow);
10702 if (foldLineBefore && foldLineBefore !== foldLine) {
10703 foldLineBefore.merge(foldLine);
10704 foldLine = foldLineBefore;
10705 }
10706 idx = foldLines.indexOf(foldLine) + 1;
10707 }
10708
10709 for (idx; idx < foldLines.length; idx++) {
10710 var foldLine = foldLines[idx];
10711 if (foldLine.start.row >= end.row) {
10712 foldLine.shiftRow(-len);
10713 }
10714 }
10715
10716 lastRow = firstRow;
10717 } else {
10718 var args = Array(len);
10719 args.unshift(firstRow, 0);
10720 var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache;
10721 arr.splice.apply(arr, args);
10722 var foldLines = this.$foldData;
10723 var foldLine = this.getFoldLine(firstRow);
10724 var idx = 0;
10725 if (foldLine) {
10726 var cmp = foldLine.range.compareInside(start.row, start.column);
10727 if (cmp == 0) {
10728 foldLine = foldLine.split(start.row, start.column);
10729 if (foldLine) {
10730 foldLine.shiftRow(len);
10731 foldLine.addRemoveChars(lastRow, 0, end.column - start.column);
10732 }
10733 } else
10734 if (cmp == -1) {
10735 foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
10736 foldLine.shiftRow(len);
10737 }
10738 idx = foldLines.indexOf(foldLine) + 1;
10739 }
10740
10741 for (idx; idx < foldLines.length; idx++) {
10742 var foldLine = foldLines[idx];
10743 if (foldLine.start.row >= firstRow) {
10744 foldLine.shiftRow(len);
10745 }
10746 }
10747 }
10748 } else {
10749 len = Math.abs(delta.start.column - delta.end.column);
10750 if (action === "remove") {
10751 removedFolds = this.getFoldsInRange(delta);
10752 this.removeFolds(removedFolds);
10753
10754 len = -len;
10755 }
10756 var foldLine = this.getFoldLine(firstRow);
10757 if (foldLine) {
10758 foldLine.addRemoveChars(firstRow, start.column, len);
10759 }
10760 }
10761
10762 if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {
10763 console.error("doc.getLength() and $wrapData.length have to be the same!");
10764 }
10765 this.$updating = false;
10766
10767 if (useWrapMode)
10768 this.$updateWrapData(firstRow, lastRow);
10769 else
10770 this.$updateRowLengthCache(firstRow, lastRow);
10771
10772 return removedFolds;
10773 };
10774
10775 this.$updateRowLengthCache = function(firstRow, lastRow, b) {
10776 this.$rowLengthCache[firstRow] = null;
10777 this.$rowLengthCache[lastRow] = null;
10778 };
10779
10780 this.$updateWrapData = function(firstRow, lastRow) {
10781 var lines = this.doc.getAllLines();
10782 var tabSize = this.getTabSize();
10783 var wrapData = this.$wrapData;
10784 var wrapLimit = this.$wrapLimit;
10785 var tokens;
10786 var foldLine;
10787
10788 var row = firstRow;
10789 lastRow = Math.min(lastRow, lines.length - 1);
10790 while (row <= lastRow) {
10791 foldLine = this.getFoldLine(row, foldLine);
10792 if (!foldLine) {
10793 tokens = this.$getDisplayTokens(lines[row]);
10794 wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
10795 row ++;
10796 } else {
10797 tokens = [];
10798 foldLine.walk(function(placeholder, row, column, lastColumn) {
10799 var walkTokens;
10800 if (placeholder != null) {
10801 walkTokens = this.$getDisplayTokens(
10802 placeholder, tokens.length);
10803 walkTokens[0] = PLACEHOLDER_START;
10804 for (var i = 1; i < walkTokens.length; i++) {
10805 walkTokens[i] = PLACEHOLDER_BODY;
10806 }
10807 } else {
10808 walkTokens = this.$getDisplayTokens(
10809 lines[row].substring(lastColumn, column),
10810 tokens.length);
10811 }
10812 tokens = tokens.concat(walkTokens);
10813 }.bind(this),
10814 foldLine.end.row,
10815 lines[foldLine.end.row].length + 1
10816 );
10817
10818 wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
10819 row = foldLine.end.row + 1;
10820 }
10821 }
10822 };
10823 var CHAR = 1,
10824 CHAR_EXT = 2,
10825 PLACEHOLDER_START = 3,
10826 PLACEHOLDER_BODY = 4,
10827 PUNCTUATION = 9,
10828 SPACE = 10,
10829 TAB = 11,
10830 TAB_SPACE = 12;
10831
10832
10833 this.$computeWrapSplits = function(tokens, wrapLimit, tabSize) {
10834 if (tokens.length == 0) {
10835 return [];
10836 }
10837
10838 var splits = [];
10839 var displayLength = tokens.length;
10840 var lastSplit = 0, lastDocSplit = 0;
10841
10842 var isCode = this.$wrapAsCode;
10843
10844 var indentedSoftWrap = this.$indentedSoftWrap;
10845 var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8)
10846 || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2);
10847
10848 function getWrapIndent() {
10849 var indentation = 0;
10850 if (maxIndent === 0)
10851 return indentation;
10852 if (indentedSoftWrap) {
10853 for (var i = 0; i < tokens.length; i++) {
10854 var token = tokens[i];
10855 if (token == SPACE)
10856 indentation += 1;
10857 else if (token == TAB)
10858 indentation += tabSize;
10859 else if (token == TAB_SPACE)
10860 continue;
10861 else
10862 break;
10863 }
10864 }
10865 if (isCode && indentedSoftWrap !== false)
10866 indentation += tabSize;
10867 return Math.min(indentation, maxIndent);
10868 }
10869 function addSplit(screenPos) {
10870 var displayed = tokens.slice(lastSplit, screenPos);
10871 var len = displayed.length;
10872 displayed.join("")
10873 .replace(/12/g, function() {
10874 len -= 1;
10875 })
10876 .replace(/2/g, function() {
10877 len -= 1;
10878 });
10879
10880 if (!splits.length) {
10881 indent = getWrapIndent();
10882 splits.indent = indent;
10883 }
10884 lastDocSplit += len;
10885 splits.push(lastDocSplit);
10886 lastSplit = screenPos;
10887 }
10888 var indent = 0;
10889 while (displayLength - lastSplit > wrapLimit - indent) {
10890 var split = lastSplit + wrapLimit - indent;
10891 if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) {
10892 addSplit(split);
10893 continue;
10894 }
10895 if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) {
10896 for (split; split != lastSplit - 1; split--) {
10897 if (tokens[split] == PLACEHOLDER_START) {
10898 break;
10899 }
10900 }
10901 if (split > lastSplit) {
10902 addSplit(split);
10903 continue;
10904 }
10905 split = lastSplit + wrapLimit;
10906 for (split; split < tokens.length; split++) {
10907 if (tokens[split] != PLACEHOLDER_BODY) {
10908 break;
10909 }
10910 }
10911 if (split == tokens.length) {
10912 break; // Breaks the while-loop.
10913 }
10914 addSplit(split);
10915 continue;
10916 }
10917 var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1);
10918 while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
10919 split --;
10920 }
10921 if (isCode) {
10922 while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
10923 split --;
10924 }
10925 while (split > minSplit && tokens[split] == PUNCTUATION) {
10926 split --;
10927 }
10928 } else {
10929 while (split > minSplit && tokens[split] < SPACE) {
10930 split --;
10931 }
10932 }
10933 if (split > minSplit) {
10934 addSplit(++split);
10935 continue;
10936 }
10937 split = lastSplit + wrapLimit;
10938 if (tokens[split] == CHAR_EXT)
10939 split--;
10940 addSplit(split - indent);
10941 }
10942 return splits;
10943 };
10944 this.$getDisplayTokens = function(str, offset) {
10945 var arr = [];
10946 var tabSize;
10947 offset = offset || 0;
10948
10949 for (var i = 0; i < str.length; i++) {
10950 var c = str.charCodeAt(i);
10951 if (c == 9) {
10952 tabSize = this.getScreenTabSize(arr.length + offset);
10953 arr.push(TAB);
10954 for (var n = 1; n < tabSize; n++) {
10955 arr.push(TAB_SPACE);
10956 }
10957 }
10958 else if (c == 32) {
10959 arr.push(SPACE);
10960 } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {
10961 arr.push(PUNCTUATION);
10962 }
10963 else if (c >= 0x1100 && isFullWidth(c)) {
10964 arr.push(CHAR, CHAR_EXT);
10965 } else {
10966 arr.push(CHAR);
10967 }
10968 }
10969 return arr;
10970 };
10971 this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
10972 if (maxScreenColumn == 0)
10973 return [0, 0];
10974 if (maxScreenColumn == null)
10975 maxScreenColumn = Infinity;
10976 screenColumn = screenColumn || 0;
10977
10978 var c, column;
10979 for (column = 0; column < str.length; column++) {
10980 c = str.charCodeAt(column);
10981 if (c == 9) {
10982 screenColumn += this.getScreenTabSize(screenColumn);
10983 }
10984 else if (c >= 0x1100 && isFullWidth(c)) {
10985 screenColumn += 2;
10986 } else {
10987 screenColumn += 1;
10988 }
10989 if (screenColumn > maxScreenColumn) {
10990 break;
10991 }
10992 }
10993
10994 return [screenColumn, column];
10995 };
10996
10997 this.lineWidgets = null;
10998 this.getRowLength = function(row) {
10999 if (this.lineWidgets)
11000 var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
11001 else
11002 h = 0;
11003 if (!this.$useWrapMode || !this.$wrapData[row]) {
11004 return 1 + h;
11005 } else {
11006 return this.$wrapData[row].length + 1 + h;
11007 }
11008 };
11009 this.getRowLineCount = function(row) {
11010 if (!this.$useWrapMode || !this.$wrapData[row]) {
11011 return 1;
11012 } else {
11013 return this.$wrapData[row].length + 1;
11014 }
11015 };
11016
11017 this.getRowWrapIndent = function(screenRow) {
11018 if (this.$useWrapMode) {
11019 var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
11020 var splits = this.$wrapData[pos.row];
11021 return splits.length && splits[0] < pos.column ? splits.indent : 0;
11022 } else {
11023 return 0;
11024 }
11025 };
11026 this.getScreenLastRowColumn = function(screenRow) {
11027 var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
11028 return this.documentToScreenColumn(pos.row, pos.column);
11029 };
11030 this.getDocumentLastRowColumn = function(docRow, docColumn) {
11031 var screenRow = this.documentToScreenRow(docRow, docColumn);
11032 return this.getScreenLastRowColumn(screenRow);
11033 };
11034 this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
11035 var screenRow = this.documentToScreenRow(docRow, docColumn);
11036 return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
11037 };
11038 this.getRowSplitData = function(row) {
11039 if (!this.$useWrapMode) {
11040 return undefined;
11041 } else {
11042 return this.$wrapData[row];
11043 }
11044 };
11045 this.getScreenTabSize = function(screenColumn) {
11046 return this.$tabSize - screenColumn % this.$tabSize;
11047 };
11048
11049
11050 this.screenToDocumentRow = function(screenRow, screenColumn) {
11051 return this.screenToDocumentPosition(screenRow, screenColumn).row;
11052 };
11053
11054
11055 this.screenToDocumentColumn = function(screenRow, screenColumn) {
11056 return this.screenToDocumentPosition(screenRow, screenColumn).column;
11057 };
11058 this.screenToDocumentPosition = function(screenRow, screenColumn, offsetX) {
11059 if (screenRow < 0)
11060 return {row: 0, column: 0};
11061
11062 var line;
11063 var docRow = 0;
11064 var docColumn = 0;
11065 var column;
11066 var row = 0;
11067 var rowLength = 0;
11068
11069 var rowCache = this.$screenRowCache;
11070 var i = this.$getRowCacheIndex(rowCache, screenRow);
11071 var l = rowCache.length;
11072 if (l && i >= 0) {
11073 var row = rowCache[i];
11074 var docRow = this.$docRowCache[i];
11075 var doCache = screenRow > rowCache[l - 1];
11076 } else {
11077 var doCache = !l;
11078 }
11079
11080 var maxRow = this.getLength() - 1;
11081 var foldLine = this.getNextFoldLine(docRow);
11082 var foldStart = foldLine ? foldLine.start.row : Infinity;
11083
11084 while (row <= screenRow) {
11085 rowLength = this.getRowLength(docRow);
11086 if (row + rowLength > screenRow || docRow >= maxRow) {
11087 break;
11088 } else {
11089 row += rowLength;
11090 docRow++;
11091 if (docRow > foldStart) {
11092 docRow = foldLine.end.row+1;
11093 foldLine = this.getNextFoldLine(docRow, foldLine);
11094 foldStart = foldLine ? foldLine.start.row : Infinity;
11095 }
11096 }
11097
11098 if (doCache) {
11099 this.$docRowCache.push(docRow);
11100 this.$screenRowCache.push(row);
11101 }
11102 }
11103
11104 if (foldLine && foldLine.start.row <= docRow) {
11105 line = this.getFoldDisplayLine(foldLine);
11106 docRow = foldLine.start.row;
11107 } else if (row + rowLength <= screenRow || docRow > maxRow) {
11108 return {
11109 row: maxRow,
11110 column: this.getLine(maxRow).length
11111 };
11112 } else {
11113 line = this.getLine(docRow);
11114 foldLine = null;
11115 }
11116 var wrapIndent = 0, splitIndex = Math.floor(screenRow - row);
11117 if (this.$useWrapMode) {
11118 var splits = this.$wrapData[docRow];
11119 if (splits) {
11120 column = splits[splitIndex];
11121 if(splitIndex > 0 && splits.length) {
11122 wrapIndent = splits.indent;
11123 docColumn = splits[splitIndex - 1] || splits[splits.length - 1];
11124 line = line.substring(docColumn);
11125 }
11126 }
11127 }
11128
11129 if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex))
11130 screenColumn = this.$bidiHandler.offsetToCol(offsetX);
11131
11132 docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1];
11133 if (this.$useWrapMode && docColumn >= column)
11134 docColumn = column - 1;
11135
11136 if (foldLine)
11137 return foldLine.idxToPosition(docColumn);
11138
11139 return {row: docRow, column: docColumn};
11140 };
11141 this.documentToScreenPosition = function(docRow, docColumn) {
11142 if (typeof docColumn === "undefined")
11143 var pos = this.$clipPositionToDocument(docRow.row, docRow.column);
11144 else
11145 pos = this.$clipPositionToDocument(docRow, docColumn);
11146
11147 docRow = pos.row;
11148 docColumn = pos.column;
11149
11150 var screenRow = 0;
11151 var foldStartRow = null;
11152 var fold = null;
11153 fold = this.getFoldAt(docRow, docColumn, 1);
11154 if (fold) {
11155 docRow = fold.start.row;
11156 docColumn = fold.start.column;
11157 }
11158
11159 var rowEnd, row = 0;
11160
11161
11162 var rowCache = this.$docRowCache;
11163 var i = this.$getRowCacheIndex(rowCache, docRow);
11164 var l = rowCache.length;
11165 if (l && i >= 0) {
11166 var row = rowCache[i];
11167 var screenRow = this.$screenRowCache[i];
11168 var doCache = docRow > rowCache[l - 1];
11169 } else {
11170 var doCache = !l;
11171 }
11172
11173 var foldLine = this.getNextFoldLine(row);
11174 var foldStart = foldLine ?foldLine.start.row :Infinity;
11175
11176 while (row < docRow) {
11177 if (row >= foldStart) {
11178 rowEnd = foldLine.end.row + 1;
11179 if (rowEnd > docRow)
11180 break;
11181 foldLine = this.getNextFoldLine(rowEnd, foldLine);
11182 foldStart = foldLine ?foldLine.start.row :Infinity;
11183 }
11184 else {
11185 rowEnd = row + 1;
11186 }
11187
11188 screenRow += this.getRowLength(row);
11189 row = rowEnd;
11190
11191 if (doCache) {
11192 this.$docRowCache.push(row);
11193 this.$screenRowCache.push(screenRow);
11194 }
11195 }
11196 var textLine = "";
11197 if (foldLine && row >= foldStart) {
11198 textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
11199 foldStartRow = foldLine.start.row;
11200 } else {
11201 textLine = this.getLine(docRow).substring(0, docColumn);
11202 foldStartRow = docRow;
11203 }
11204 var wrapIndent = 0;
11205 if (this.$useWrapMode) {
11206 var wrapRow = this.$wrapData[foldStartRow];
11207 if (wrapRow) {
11208 var screenRowOffset = 0;
11209 while (textLine.length >= wrapRow[screenRowOffset]) {
11210 screenRow ++;
11211 screenRowOffset++;
11212 }
11213 textLine = textLine.substring(
11214 wrapRow[screenRowOffset - 1] || 0, textLine.length
11215 );
11216 wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;
11217 }
11218 }
11219
11220 return {
11221 row: screenRow,
11222 column: wrapIndent + this.$getStringScreenWidth(textLine)[0]
11223 };
11224 };
11225 this.documentToScreenColumn = function(row, docColumn) {
11226 return this.documentToScreenPosition(row, docColumn).column;
11227 };
11228 this.documentToScreenRow = function(docRow, docColumn) {
11229 return this.documentToScreenPosition(docRow, docColumn).row;
11230 };
11231 this.getScreenLength = function() {
11232 var screenRows = 0;
11233 var fold = null;
11234 if (!this.$useWrapMode) {
11235 screenRows = this.getLength();
11236 var foldData = this.$foldData;
11237 for (var i = 0; i < foldData.length; i++) {
11238 fold = foldData[i];
11239 screenRows -= fold.end.row - fold.start.row;
11240 }
11241 } else {
11242 var lastRow = this.$wrapData.length;
11243 var row = 0, i = 0;
11244 var fold = this.$foldData[i++];
11245 var foldStart = fold ? fold.start.row :Infinity;
11246
11247 while (row < lastRow) {
11248 var splits = this.$wrapData[row];
11249 screenRows += splits ? splits.length + 1 : 1;
11250 row ++;
11251 if (row > foldStart) {
11252 row = fold.end.row+1;
11253 fold = this.$foldData[i++];
11254 foldStart = fold ?fold.start.row :Infinity;
11255 }
11256 }
11257 }
11258 if (this.lineWidgets)
11259 screenRows += this.$getWidgetScreenLength();
11260
11261 return screenRows;
11262 };
11263 this.$setFontMetrics = function(fm) {
11264 if (!this.$enableVarChar) return;
11265 this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
11266 if (maxScreenColumn === 0)
11267 return [0, 0];
11268 if (!maxScreenColumn)
11269 maxScreenColumn = Infinity;
11270 screenColumn = screenColumn || 0;
11271
11272 var c, column;
11273 for (column = 0; column < str.length; column++) {
11274 c = str.charAt(column);
11275 if (c === "\t") {
11276 screenColumn += this.getScreenTabSize(screenColumn);
11277 } else {
11278 screenColumn += fm.getCharacterWidth(c);
11279 }
11280 if (screenColumn > maxScreenColumn) {
11281 break;
11282 }
11283 }
11284
11285 return [screenColumn, column];
11286 };
11287 };
11288
11289 this.destroy = function() {
11290 if (this.bgTokenizer) {
11291 this.bgTokenizer.setDocument(null);
11292 this.bgTokenizer = null;
11293 }
11294 this.$stopWorker();
11295 };
11296
11297 this.isFullWidth = isFullWidth;
11298 function isFullWidth(c) {
11299 if (c < 0x1100)
11300 return false;
11301 return c >= 0x1100 && c <= 0x115F ||
11302 c >= 0x11A3 && c <= 0x11A7 ||
11303 c >= 0x11FA && c <= 0x11FF ||
11304 c >= 0x2329 && c <= 0x232A ||
11305 c >= 0x2E80 && c <= 0x2E99 ||
11306 c >= 0x2E9B && c <= 0x2EF3 ||
11307 c >= 0x2F00 && c <= 0x2FD5 ||
11308 c >= 0x2FF0 && c <= 0x2FFB ||
11309 c >= 0x3000 && c <= 0x303E ||
11310 c >= 0x3041 && c <= 0x3096 ||
11311 c >= 0x3099 && c <= 0x30FF ||
11312 c >= 0x3105 && c <= 0x312D ||
11313 c >= 0x3131 && c <= 0x318E ||
11314 c >= 0x3190 && c <= 0x31BA ||
11315 c >= 0x31C0 && c <= 0x31E3 ||
11316 c >= 0x31F0 && c <= 0x321E ||
11317 c >= 0x3220 && c <= 0x3247 ||
11318 c >= 0x3250 && c <= 0x32FE ||
11319 c >= 0x3300 && c <= 0x4DBF ||
11320 c >= 0x4E00 && c <= 0xA48C ||
11321 c >= 0xA490 && c <= 0xA4C6 ||
11322 c >= 0xA960 && c <= 0xA97C ||
11323 c >= 0xAC00 && c <= 0xD7A3 ||
11324 c >= 0xD7B0 && c <= 0xD7C6 ||
11325 c >= 0xD7CB && c <= 0xD7FB ||
11326 c >= 0xF900 && c <= 0xFAFF ||
11327 c >= 0xFE10 && c <= 0xFE19 ||
11328 c >= 0xFE30 && c <= 0xFE52 ||
11329 c >= 0xFE54 && c <= 0xFE66 ||
11330 c >= 0xFE68 && c <= 0xFE6B ||
11331 c >= 0xFF01 && c <= 0xFF60 ||
11332 c >= 0xFFE0 && c <= 0xFFE6;
11333 }
11334
11335 }).call(EditSession.prototype);
11336
11337 require("./edit_session/folding").Folding.call(EditSession.prototype);
11338 require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
11339
11340
11341 config.defineOptions(EditSession.prototype, "session", {
11342 wrap: {
11343 set: function(value) {
11344 if (!value || value == "off")
11345 value = false;
11346 else if (value == "free")
11347 value = true;
11348 else if (value == "printMargin")
11349 value = -1;
11350 else if (typeof value == "string")
11351 value = parseInt(value, 10) || false;
11352
11353 if (this.$wrap == value)
11354 return;
11355 this.$wrap = value;
11356 if (!value) {
11357 this.setUseWrapMode(false);
11358 } else {
11359 var col = typeof value == "number" ? value : null;
11360 this.setWrapLimitRange(col, col);
11361 this.setUseWrapMode(true);
11362 }
11363 },
11364 get: function() {
11365 if (this.getUseWrapMode()) {
11366 if (this.$wrap == -1)
11367 return "printMargin";
11368 if (!this.getWrapLimitRange().min)
11369 return "free";
11370 return this.$wrap;
11371 }
11372 return "off";
11373 },
11374 handlesSet: true
11375 },
11376 wrapMethod: {
11377 set: function(val) {
11378 val = val == "auto"
11379 ? this.$mode.type != "text"
11380 : val != "text";
11381 if (val != this.$wrapAsCode) {
11382 this.$wrapAsCode = val;
11383 if (this.$useWrapMode) {
11384 this.$modified = true;
11385 this.$resetRowCache(0);
11386 this.$updateWrapData(0, this.getLength() - 1);
11387 }
11388 }
11389 },
11390 initialValue: "auto"
11391 },
11392 indentedSoftWrap: { initialValue: true },
11393 firstLineNumber: {
11394 set: function() {this._signal("changeBreakpoint");},
11395 initialValue: 1
11396 },
11397 useWorker: {
11398 set: function(useWorker) {
11399 this.$useWorker = useWorker;
11400
11401 this.$stopWorker();
11402 if (useWorker)
11403 this.$startWorker();
11404 },
11405 initialValue: true
11406 },
11407 useSoftTabs: {initialValue: true},
11408 tabSize: {
11409 set: function(tabSize) {
11410 if (isNaN(tabSize) || this.$tabSize === tabSize) return;
11411
11412 this.$modified = true;
11413 this.$rowLengthCache = [];
11414 this.$tabSize = tabSize;
11415 this._signal("changeTabSize");
11416 },
11417 initialValue: 4,
11418 handlesSet: true
11419 },
11420 navigateWithinSoftTabs: {initialValue: false},
11421 overwrite: {
11422 set: function(val) {this._signal("changeOverwrite");},
11423 initialValue: false
11424 },
11425 newLineMode: {
11426 set: function(val) {this.doc.setNewLineMode(val);},
11427 get: function() {return this.doc.getNewLineMode();},
11428 handlesSet: true
11429 },
11430 mode: {
11431 set: function(val) { this.setMode(val); },
11432 get: function() { return this.$modeId; }
11433 }
11434 });
11435
11436 exports.EditSession = EditSession;
11437 });
11438
11439 define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) {
11440 "use strict";
11441
11442 var lang = require("./lib/lang");
11443 var oop = require("./lib/oop");
11444 var Range = require("./range").Range;
11445
11446 var Search = function() {
11447 this.$options = {};
11448 };
11449
11450 (function() {
11451 this.set = function(options) {
11452 oop.mixin(this.$options, options);
11453 return this;
11454 };
11455 this.getOptions = function() {
11456 return lang.copyObject(this.$options);
11457 };
11458 this.setOptions = function(options) {
11459 this.$options = options;
11460 };
11461 this.find = function(session) {
11462 var options = this.$options;
11463 var iterator = this.$matchIterator(session, options);
11464 if (!iterator)
11465 return false;
11466
11467 var firstRange = null;
11468 iterator.forEach(function(sr, sc, er, ec) {
11469 firstRange = new Range(sr, sc, er, ec);
11470 if (sc == ec && options.start && options.start.start
11471 && options.skipCurrent != false && firstRange.isEqual(options.start)
11472 ) {
11473 firstRange = null;
11474 return false;
11475 }
11476
11477 return true;
11478 });
11479
11480 return firstRange;
11481 };
11482 this.findAll = function(session) {
11483 var options = this.$options;
11484 if (!options.needle)
11485 return [];
11486 this.$assembleRegExp(options);
11487
11488 var range = options.range;
11489 var lines = range
11490 ? session.getLines(range.start.row, range.end.row)
11491 : session.doc.getAllLines();
11492
11493 var ranges = [];
11494 var re = options.re;
11495 if (options.$isMultiLine) {
11496 var len = re.length;
11497 var maxRow = lines.length - len;
11498 var prevRange;
11499 outer: for (var row = re.offset || 0; row <= maxRow; row++) {
11500 for (var j = 0; j < len; j++)
11501 if (lines[row + j].search(re[j]) == -1)
11502 continue outer;
11503
11504 var startLine = lines[row];
11505 var line = lines[row + len - 1];
11506 var startIndex = startLine.length - startLine.match(re[0])[0].length;
11507 var endIndex = line.match(re[len - 1])[0].length;
11508
11509 if (prevRange && prevRange.end.row === row &&
11510 prevRange.end.column > startIndex
11511 ) {
11512 continue;
11513 }
11514 ranges.push(prevRange = new Range(
11515 row, startIndex, row + len - 1, endIndex
11516 ));
11517 if (len > 2)
11518 row = row + len - 2;
11519 }
11520 } else {
11521 for (var i = 0; i < lines.length; i++) {
11522 var matches = lang.getMatchOffsets(lines[i], re);
11523 for (var j = 0; j < matches.length; j++) {
11524 var match = matches[j];
11525 ranges.push(new Range(i, match.offset, i, match.offset + match.length));
11526 }
11527 }
11528 }
11529
11530 if (range) {
11531 var startColumn = range.start.column;
11532 var endColumn = range.start.column;
11533 var i = 0, j = ranges.length - 1;
11534 while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)
11535 i++;
11536
11537 while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)
11538 j--;
11539
11540 ranges = ranges.slice(i, j + 1);
11541 for (i = 0, j = ranges.length; i < j; i++) {
11542 ranges[i].start.row += range.start.row;
11543 ranges[i].end.row += range.start.row;
11544 }
11545 }
11546
11547 return ranges;
11548 };
11549 this.replace = function(input, replacement) {
11550 var options = this.$options;
11551
11552 var re = this.$assembleRegExp(options);
11553 if (options.$isMultiLine)
11554 return replacement;
11555
11556 if (!re)
11557 return;
11558
11559 var match = re.exec(input);
11560 if (!match || match[0].length != input.length)
11561 return null;
11562
11563 replacement = input.replace(re, replacement);
11564 if (options.preserveCase) {
11565 replacement = replacement.split("");
11566 for (var i = Math.min(input.length, input.length); i--; ) {
11567 var ch = input[i];
11568 if (ch && ch.toLowerCase() != ch)
11569 replacement[i] = replacement[i].toUpperCase();
11570 else
11571 replacement[i] = replacement[i].toLowerCase();
11572 }
11573 replacement = replacement.join("");
11574 }
11575
11576 return replacement;
11577 };
11578
11579 this.$assembleRegExp = function(options, $disableFakeMultiline) {
11580 if (options.needle instanceof RegExp)
11581 return options.re = options.needle;
11582
11583 var needle = options.needle;
11584
11585 if (!options.needle)
11586 return options.re = false;
11587
11588 if (!options.regExp)
11589 needle = lang.escapeRegExp(needle);
11590
11591 if (options.wholeWord)
11592 needle = addWordBoundary(needle, options);
11593
11594 var modifier = options.caseSensitive ? "gm" : "gmi";
11595
11596 options.$isMultiLine = !$disableFakeMultiline && /[\n\r]/.test(needle);
11597 if (options.$isMultiLine)
11598 return options.re = this.$assembleMultilineRegExp(needle, modifier);
11599
11600 try {
11601 var re = new RegExp(needle, modifier);
11602 } catch(e) {
11603 re = false;
11604 }
11605 return options.re = re;
11606 };
11607
11608 this.$assembleMultilineRegExp = function(needle, modifier) {
11609 var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n");
11610 var re = [];
11611 for (var i = 0; i < parts.length; i++) try {
11612 re.push(new RegExp(parts[i], modifier));
11613 } catch(e) {
11614 return false;
11615 }
11616 return re;
11617 };
11618
11619 this.$matchIterator = function(session, options) {
11620 var re = this.$assembleRegExp(options);
11621 if (!re)
11622 return false;
11623 var backwards = options.backwards == true;
11624 var skipCurrent = options.skipCurrent != false;
11625
11626 var range = options.range;
11627 var start = options.start;
11628 if (!start)
11629 start = range ? range[backwards ? "end" : "start"] : session.selection.getRange();
11630
11631 if (start.start)
11632 start = start[skipCurrent != backwards ? "end" : "start"];
11633
11634 var firstRow = range ? range.start.row : 0;
11635 var lastRow = range ? range.end.row : session.getLength() - 1;
11636
11637 if (backwards) {
11638 var forEach = function(callback) {
11639 var row = start.row;
11640 if (forEachInLine(row, start.column, callback))
11641 return;
11642 for (row--; row >= firstRow; row--)
11643 if (forEachInLine(row, Number.MAX_VALUE, callback))
11644 return;
11645 if (options.wrap == false)
11646 return;
11647 for (row = lastRow, firstRow = start.row; row >= firstRow; row--)
11648 if (forEachInLine(row, Number.MAX_VALUE, callback))
11649 return;
11650 };
11651 }
11652 else {
11653 var forEach = function(callback) {
11654 var row = start.row;
11655 if (forEachInLine(row, start.column, callback))
11656 return;
11657 for (row = row + 1; row <= lastRow; row++)
11658 if (forEachInLine(row, 0, callback))
11659 return;
11660 if (options.wrap == false)
11661 return;
11662 for (row = firstRow, lastRow = start.row; row <= lastRow; row++)
11663 if (forEachInLine(row, 0, callback))
11664 return;
11665 };
11666 }
11667
11668 if (options.$isMultiLine) {
11669 var len = re.length;
11670 var forEachInLine = function(row, offset, callback) {
11671 var startRow = backwards ? row - len + 1 : row;
11672 if (startRow < 0) return;
11673 var line = session.getLine(startRow);
11674 var startIndex = line.search(re[0]);
11675 if (!backwards && startIndex < offset || startIndex === -1) return;
11676 for (var i = 1; i < len; i++) {
11677 line = session.getLine(startRow + i);
11678 if (line.search(re[i]) == -1)
11679 return;
11680 }
11681 var endIndex = line.match(re[len - 1])[0].length;
11682 if (backwards && endIndex > offset) return;
11683 if (callback(startRow, startIndex, startRow + len - 1, endIndex))
11684 return true;
11685 };
11686 }
11687 else if (backwards) {
11688 var forEachInLine = function(row, endIndex, callback) {
11689 var line = session.getLine(row);
11690 var matches = [];
11691 var m, last = 0;
11692 re.lastIndex = 0;
11693 while((m = re.exec(line))) {
11694 var length = m[0].length;
11695 last = m.index;
11696 if (!length) {
11697 if (last >= line.length) break;
11698 re.lastIndex = last += 1;
11699 }
11700 if (m.index + length > endIndex)
11701 break;
11702 matches.push(m.index, length);
11703 }
11704 for (var i = matches.length - 1; i >= 0; i -= 2) {
11705 var column = matches[i - 1];
11706 var length = matches[i];
11707 if (callback(row, column, row, column + length))
11708 return true;
11709 }
11710 };
11711 }
11712 else {
11713 var forEachInLine = function(row, startIndex, callback) {
11714 var line = session.getLine(row);
11715 var m;
11716 var last = startIndex;
11717 re.lastIndex = startIndex;
11718 while((m = re.exec(line))) {
11719 var length = m[0].length;
11720 last = m.index;
11721 if (callback(row, last, row,last + length))
11722 return true;
11723 if (!length) {
11724 re.lastIndex = last += 1;
11725 if (last >= line.length) return false;
11726 }
11727 }
11728 };
11729 }
11730 return {forEach: forEach};
11731 };
11732
11733 }).call(Search.prototype);
11734
11735 function addWordBoundary(needle, options) {
11736 function wordBoundary(c) {
11737 if (/\w/.test(c) || options.regExp) return "\\b";
11738 return "";
11739 }
11740 return wordBoundary(needle[0]) + needle
11741 + wordBoundary(needle[needle.length - 1]);
11742 }
11743
11744 exports.Search = Search;
11745 });
11746
11747 define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) {
11748 "use strict";
11749
11750 var keyUtil = require("../lib/keys");
11751 var useragent = require("../lib/useragent");
11752 var KEY_MODS = keyUtil.KEY_MODS;
11753
11754 function HashHandler(config, platform) {
11755 this.platform = platform || (useragent.isMac ? "mac" : "win");
11756 this.commands = {};
11757 this.commandKeyBinding = {};
11758 this.addCommands(config);
11759 this.$singleCommand = true;
11760 }
11761
11762 function MultiHashHandler(config, platform) {
11763 HashHandler.call(this, config, platform);
11764 this.$singleCommand = false;
11765 }
11766
11767 MultiHashHandler.prototype = HashHandler.prototype;
11768
11769 (function() {
11770
11771
11772 this.addCommand = function(command) {
11773 if (this.commands[command.name])
11774 this.removeCommand(command);
11775
11776 this.commands[command.name] = command;
11777
11778 if (command.bindKey)
11779 this._buildKeyHash(command);
11780 };
11781
11782 this.removeCommand = function(command, keepCommand) {
11783 var name = command && (typeof command === 'string' ? command : command.name);
11784 command = this.commands[name];
11785 if (!keepCommand)
11786 delete this.commands[name];
11787 var ckb = this.commandKeyBinding;
11788 for (var keyId in ckb) {
11789 var cmdGroup = ckb[keyId];
11790 if (cmdGroup == command) {
11791 delete ckb[keyId];
11792 } else if (Array.isArray(cmdGroup)) {
11793 var i = cmdGroup.indexOf(command);
11794 if (i != -1) {
11795 cmdGroup.splice(i, 1);
11796 if (cmdGroup.length == 1)
11797 ckb[keyId] = cmdGroup[0];
11798 }
11799 }
11800 }
11801 };
11802
11803 this.bindKey = function(key, command, position) {
11804 if (typeof key == "object" && key) {
11805 if (position == undefined)
11806 position = key.position;
11807 key = key[this.platform];
11808 }
11809 if (!key)
11810 return;
11811 if (typeof command == "function")
11812 return this.addCommand({exec: command, bindKey: key, name: command.name || key});
11813
11814 key.split("|").forEach(function(keyPart) {
11815 var chain = "";
11816 if (keyPart.indexOf(" ") != -1) {
11817 var parts = keyPart.split(/\s+/);
11818 keyPart = parts.pop();
11819 parts.forEach(function(keyPart) {
11820 var binding = this.parseKeys(keyPart);
11821 var id = KEY_MODS[binding.hashId] + binding.key;
11822 chain += (chain ? " " : "") + id;
11823 this._addCommandToBinding(chain, "chainKeys");
11824 }, this);
11825 chain += " ";
11826 }
11827 var binding = this.parseKeys(keyPart);
11828 var id = KEY_MODS[binding.hashId] + binding.key;
11829 this._addCommandToBinding(chain + id, command, position);
11830 }, this);
11831 };
11832
11833 function getPosition(command) {
11834 return typeof command == "object" && command.bindKey
11835 && command.bindKey.position
11836 || (command.isDefault ? -100 : 0);
11837 }
11838 this._addCommandToBinding = function(keyId, command, position) {
11839 var ckb = this.commandKeyBinding, i;
11840 if (!command) {
11841 delete ckb[keyId];
11842 } else if (!ckb[keyId] || this.$singleCommand) {
11843 ckb[keyId] = command;
11844 } else {
11845 if (!Array.isArray(ckb[keyId])) {
11846 ckb[keyId] = [ckb[keyId]];
11847 } else if ((i = ckb[keyId].indexOf(command)) != -1) {
11848 ckb[keyId].splice(i, 1);
11849 }
11850
11851 if (typeof position != "number") {
11852 position = getPosition(command);
11853 }
11854
11855 var commands = ckb[keyId];
11856 for (i = 0; i < commands.length; i++) {
11857 var other = commands[i];
11858 var otherPos = getPosition(other);
11859 if (otherPos > position)
11860 break;
11861 }
11862 commands.splice(i, 0, command);
11863 }
11864 };
11865
11866 this.addCommands = function(commands) {
11867 commands && Object.keys(commands).forEach(function(name) {
11868 var command = commands[name];
11869 if (!command)
11870 return;
11871
11872 if (typeof command === "string")
11873 return this.bindKey(command, name);
11874
11875 if (typeof command === "function")
11876 command = { exec: command };
11877
11878 if (typeof command !== "object")
11879 return;
11880
11881 if (!command.name)
11882 command.name = name;
11883
11884 this.addCommand(command);
11885 }, this);
11886 };
11887
11888 this.removeCommands = function(commands) {
11889 Object.keys(commands).forEach(function(name) {
11890 this.removeCommand(commands[name]);
11891 }, this);
11892 };
11893
11894 this.bindKeys = function(keyList) {
11895 Object.keys(keyList).forEach(function(key) {
11896 this.bindKey(key, keyList[key]);
11897 }, this);
11898 };
11899
11900 this._buildKeyHash = function(command) {
11901 this.bindKey(command.bindKey, command);
11902 };
11903 this.parseKeys = function(keys) {
11904 var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x;});
11905 var key = parts.pop();
11906
11907 var keyCode = keyUtil[key];
11908 if (keyUtil.FUNCTION_KEYS[keyCode])
11909 key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();
11910 else if (!parts.length)
11911 return {key: key, hashId: -1};
11912 else if (parts.length == 1 && parts[0] == "shift")
11913 return {key: key.toUpperCase(), hashId: -1};
11914
11915 var hashId = 0;
11916 for (var i = parts.length; i--;) {
11917 var modifier = keyUtil.KEY_MODS[parts[i]];
11918 if (modifier == null) {
11919 if (typeof console != "undefined")
11920 console.error("invalid modifier " + parts[i] + " in " + keys);
11921 return false;
11922 }
11923 hashId |= modifier;
11924 }
11925 return {key: key, hashId: hashId};
11926 };
11927
11928 this.findKeyCommand = function findKeyCommand(hashId, keyString) {
11929 var key = KEY_MODS[hashId] + keyString;
11930 return this.commandKeyBinding[key];
11931 };
11932
11933 this.handleKeyboard = function(data, hashId, keyString, keyCode) {
11934 if (keyCode < 0) return;
11935 var key = KEY_MODS[hashId] + keyString;
11936 var command = this.commandKeyBinding[key];
11937 if (data.$keyChain) {
11938 data.$keyChain += " " + key;
11939 command = this.commandKeyBinding[data.$keyChain] || command;
11940 }
11941
11942 if (command) {
11943 if (command == "chainKeys" || command[command.length - 1] == "chainKeys") {
11944 data.$keyChain = data.$keyChain || key;
11945 return {command: "null"};
11946 }
11947 }
11948
11949 if (data.$keyChain) {
11950 if ((!hashId || hashId == 4) && keyString.length == 1)
11951 data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input
11952 else if (hashId == -1 || keyCode > 0)
11953 data.$keyChain = ""; // reset keyChain
11954 }
11955 return {command: command};
11956 };
11957
11958 this.getStatusText = function(editor, data) {
11959 return data.$keyChain || "";
11960 };
11961
11962 }).call(HashHandler.prototype);
11963
11964 exports.HashHandler = HashHandler;
11965 exports.MultiHashHandler = MultiHashHandler;
11966 });
11967
11968 define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"], function(require, exports, module) {
11969 "use strict";
11970
11971 var oop = require("../lib/oop");
11972 var MultiHashHandler = require("../keyboard/hash_handler").MultiHashHandler;
11973 var EventEmitter = require("../lib/event_emitter").EventEmitter;
11974
11975 var CommandManager = function(platform, commands) {
11976 MultiHashHandler.call(this, commands, platform);
11977 this.byName = this.commands;
11978 this.setDefaultHandler("exec", function(e) {
11979 return e.command.exec(e.editor, e.args || {});
11980 });
11981 };
11982
11983 oop.inherits(CommandManager, MultiHashHandler);
11984
11985 (function() {
11986
11987 oop.implement(this, EventEmitter);
11988
11989 this.exec = function(command, editor, args) {
11990 if (Array.isArray(command)) {
11991 for (var i = command.length; i--; ) {
11992 if (this.exec(command[i], editor, args)) return true;
11993 }
11994 return false;
11995 }
11996
11997 if (typeof command === "string")
11998 command = this.commands[command];
11999
12000 if (!command)
12001 return false;
12002
12003 if (editor && editor.$readOnly && !command.readOnly)
12004 return false;
12005
12006 if (command.isAvailable && !command.isAvailable(editor))
12007 return false;
12008
12009 var e = {editor: editor, command: command, args: args};
12010 e.returnValue = this._emit("exec", e);
12011 this._signal("afterExec", e);
12012
12013 return e.returnValue === false ? false : true;
12014 };
12015
12016 this.toggleRecording = function(editor) {
12017 if (this.$inReplay)
12018 return;
12019
12020 editor && editor._emit("changeStatus");
12021 if (this.recording) {
12022 this.macro.pop();
12023 this.removeEventListener("exec", this.$addCommandToMacro);
12024
12025 if (!this.macro.length)
12026 this.macro = this.oldMacro;
12027
12028 return this.recording = false;
12029 }
12030 if (!this.$addCommandToMacro) {
12031 this.$addCommandToMacro = function(e) {
12032 this.macro.push([e.command, e.args]);
12033 }.bind(this);
12034 }
12035
12036 this.oldMacro = this.macro;
12037 this.macro = [];
12038 this.on("exec", this.$addCommandToMacro);
12039 return this.recording = true;
12040 };
12041
12042 this.replay = function(editor) {
12043 if (this.$inReplay || !this.macro)
12044 return;
12045
12046 if (this.recording)
12047 return this.toggleRecording(editor);
12048
12049 try {
12050 this.$inReplay = true;
12051 this.macro.forEach(function(x) {
12052 if (typeof x == "string")
12053 this.exec(x, editor);
12054 else
12055 this.exec(x[0], editor, x[1]);
12056 }, this);
12057 } finally {
12058 this.$inReplay = false;
12059 }
12060 };
12061
12062 this.trimMacro = function(m) {
12063 return m.map(function(x){
12064 if (typeof x[0] != "string")
12065 x[0] = x[0].name;
12066 if (!x[1])
12067 x = x[0];
12068 return x;
12069 });
12070 };
12071
12072 }).call(CommandManager.prototype);
12073
12074 exports.CommandManager = CommandManager;
12075
12076 });
12077
12078 define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"], function(require, exports, module) {
12079 "use strict";
12080
12081 var lang = require("../lib/lang");
12082 var config = require("../config");
12083 var Range = require("../range").Range;
12084
12085 function bindKey(win, mac) {
12086 return {win: win, mac: mac};
12087 }
12088 exports.commands = [{
12089 name: "showSettingsMenu",
12090 bindKey: bindKey("Ctrl-,", "Command-,"),
12091 exec: function(editor) {
12092 config.loadModule("ace/ext/settings_menu", function(module) {
12093 module.init(editor);
12094 editor.showSettingsMenu();
12095 });
12096 },
12097 readOnly: true
12098 }, {
12099 name: "goToNextError",
12100 bindKey: bindKey("Alt-E", "F4"),
12101 exec: function(editor) {
12102 config.loadModule("ace/ext/error_marker", function(module) {
12103 module.showErrorMarker(editor, 1);
12104 });
12105 },
12106 scrollIntoView: "animate",
12107 readOnly: true
12108 }, {
12109 name: "goToPreviousError",
12110 bindKey: bindKey("Alt-Shift-E", "Shift-F4"),
12111 exec: function(editor) {
12112 config.loadModule("ace/ext/error_marker", function(module) {
12113 module.showErrorMarker(editor, -1);
12114 });
12115 },
12116 scrollIntoView: "animate",
12117 readOnly: true
12118 }, {
12119 name: "selectall",
12120 bindKey: bindKey("Ctrl-A", "Command-A"),
12121 exec: function(editor) { editor.selectAll(); },
12122 readOnly: true
12123 }, {
12124 name: "centerselection",
12125 bindKey: bindKey(null, "Ctrl-L"),
12126 exec: function(editor) { editor.centerSelection(); },
12127 readOnly: true
12128 }, {
12129 name: "gotoline",
12130 bindKey: bindKey("Ctrl-L", "Command-L"),
12131 exec: function(editor) {
12132 var line = parseInt(prompt("Enter line number:"), 10);
12133 if (!isNaN(line)) {
12134 editor.gotoLine(line);
12135 }
12136 },
12137 readOnly: true
12138 }, {
12139 name: "fold",
12140 bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
12141 exec: function(editor) { editor.session.toggleFold(false); },
12142 multiSelectAction: "forEach",
12143 scrollIntoView: "center",
12144 readOnly: true
12145 }, {
12146 name: "unfold",
12147 bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
12148 exec: function(editor) { editor.session.toggleFold(true); },
12149 multiSelectAction: "forEach",
12150 scrollIntoView: "center",
12151 readOnly: true
12152 }, {
12153 name: "toggleFoldWidget",
12154 bindKey: bindKey("F2", "F2"),
12155 exec: function(editor) { editor.session.toggleFoldWidget(); },
12156 multiSelectAction: "forEach",
12157 scrollIntoView: "center",
12158 readOnly: true
12159 }, {
12160 name: "toggleParentFoldWidget",
12161 bindKey: bindKey("Alt-F2", "Alt-F2"),
12162 exec: function(editor) { editor.session.toggleFoldWidget(true); },
12163 multiSelectAction: "forEach",
12164 scrollIntoView: "center",
12165 readOnly: true
12166 }, {
12167 name: "foldall",
12168 bindKey: bindKey(null, "Ctrl-Command-Option-0"),
12169 exec: function(editor) { editor.session.foldAll(); },
12170 scrollIntoView: "center",
12171 readOnly: true
12172 }, {
12173 name: "foldOther",
12174 bindKey: bindKey("Alt-0", "Command-Option-0"),
12175 exec: function(editor) {
12176 editor.session.foldAll();
12177 editor.session.unfold(editor.selection.getAllRanges());
12178 },
12179 scrollIntoView: "center",
12180 readOnly: true
12181 }, {
12182 name: "unfoldall",
12183 bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
12184 exec: function(editor) { editor.session.unfold(); },
12185 scrollIntoView: "center",
12186 readOnly: true
12187 }, {
12188 name: "findnext",
12189 bindKey: bindKey("Ctrl-K", "Command-G"),
12190 exec: function(editor) { editor.findNext(); },
12191 multiSelectAction: "forEach",
12192 scrollIntoView: "center",
12193 readOnly: true
12194 }, {
12195 name: "findprevious",
12196 bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
12197 exec: function(editor) { editor.findPrevious(); },
12198 multiSelectAction: "forEach",
12199 scrollIntoView: "center",
12200 readOnly: true
12201 }, {
12202 name: "selectOrFindNext",
12203 bindKey: bindKey("Alt-K", "Ctrl-G"),
12204 exec: function(editor) {
12205 if (editor.selection.isEmpty())
12206 editor.selection.selectWord();
12207 else
12208 editor.findNext();
12209 },
12210 readOnly: true
12211 }, {
12212 name: "selectOrFindPrevious",
12213 bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"),
12214 exec: function(editor) {
12215 if (editor.selection.isEmpty())
12216 editor.selection.selectWord();
12217 else
12218 editor.findPrevious();
12219 },
12220 readOnly: true
12221 }, {
12222 name: "find",
12223 bindKey: bindKey("Ctrl-F", "Command-F"),
12224 exec: function(editor) {
12225 config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor);});
12226 },
12227 readOnly: true
12228 }, {
12229 name: "overwrite",
12230 bindKey: "Insert",
12231 exec: function(editor) { editor.toggleOverwrite(); },
12232 readOnly: true
12233 }, {
12234 name: "selecttostart",
12235 bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Home|Command-Shift-Up"),
12236 exec: function(editor) { editor.getSelection().selectFileStart(); },
12237 multiSelectAction: "forEach",
12238 readOnly: true,
12239 scrollIntoView: "animate",
12240 aceCommandGroup: "fileJump"
12241 }, {
12242 name: "gotostart",
12243 bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
12244 exec: function(editor) { editor.navigateFileStart(); },
12245 multiSelectAction: "forEach",
12246 readOnly: true,
12247 scrollIntoView: "animate",
12248 aceCommandGroup: "fileJump"
12249 }, {
12250 name: "selectup",
12251 bindKey: bindKey("Shift-Up", "Shift-Up|Ctrl-Shift-P"),
12252 exec: function(editor) { editor.getSelection().selectUp(); },
12253 multiSelectAction: "forEach",
12254 scrollIntoView: "cursor",
12255 readOnly: true
12256 }, {
12257 name: "golineup",
12258 bindKey: bindKey("Up", "Up|Ctrl-P"),
12259 exec: function(editor, args) { editor.navigateUp(args.times); },
12260 multiSelectAction: "forEach",
12261 scrollIntoView: "cursor",
12262 readOnly: true
12263 }, {
12264 name: "selecttoend",
12265 bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-End|Command-Shift-Down"),
12266 exec: function(editor) { editor.getSelection().selectFileEnd(); },
12267 multiSelectAction: "forEach",
12268 readOnly: true,
12269 scrollIntoView: "animate",
12270 aceCommandGroup: "fileJump"
12271 }, {
12272 name: "gotoend",
12273 bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
12274 exec: function(editor) { editor.navigateFileEnd(); },
12275 multiSelectAction: "forEach",
12276 readOnly: true,
12277 scrollIntoView: "animate",
12278 aceCommandGroup: "fileJump"
12279 }, {
12280 name: "selectdown",
12281 bindKey: bindKey("Shift-Down", "Shift-Down|Ctrl-Shift-N"),
12282 exec: function(editor) { editor.getSelection().selectDown(); },
12283 multiSelectAction: "forEach",
12284 scrollIntoView: "cursor",
12285 readOnly: true
12286 }, {
12287 name: "golinedown",
12288 bindKey: bindKey("Down", "Down|Ctrl-N"),
12289 exec: function(editor, args) { editor.navigateDown(args.times); },
12290 multiSelectAction: "forEach",
12291 scrollIntoView: "cursor",
12292 readOnly: true
12293 }, {
12294 name: "selectwordleft",
12295 bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
12296 exec: function(editor) { editor.getSelection().selectWordLeft(); },
12297 multiSelectAction: "forEach",
12298 scrollIntoView: "cursor",
12299 readOnly: true
12300 }, {
12301 name: "gotowordleft",
12302 bindKey: bindKey("Ctrl-Left", "Option-Left"),
12303 exec: function(editor) { editor.navigateWordLeft(); },
12304 multiSelectAction: "forEach",
12305 scrollIntoView: "cursor",
12306 readOnly: true
12307 }, {
12308 name: "selecttolinestart",
12309 bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left|Ctrl-Shift-A"),
12310 exec: function(editor) { editor.getSelection().selectLineStart(); },
12311 multiSelectAction: "forEach",
12312 scrollIntoView: "cursor",
12313 readOnly: true
12314 }, {
12315 name: "gotolinestart",
12316 bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
12317 exec: function(editor) { editor.navigateLineStart(); },
12318 multiSelectAction: "forEach",
12319 scrollIntoView: "cursor",
12320 readOnly: true
12321 }, {
12322 name: "selectleft",
12323 bindKey: bindKey("Shift-Left", "Shift-Left|Ctrl-Shift-B"),
12324 exec: function(editor) { editor.getSelection().selectLeft(); },
12325 multiSelectAction: "forEach",
12326 scrollIntoView: "cursor",
12327 readOnly: true
12328 }, {
12329 name: "gotoleft",
12330 bindKey: bindKey("Left", "Left|Ctrl-B"),
12331 exec: function(editor, args) { editor.navigateLeft(args.times); },
12332 multiSelectAction: "forEach",
12333 scrollIntoView: "cursor",
12334 readOnly: true
12335 }, {
12336 name: "selectwordright",
12337 bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
12338 exec: function(editor) { editor.getSelection().selectWordRight(); },
12339 multiSelectAction: "forEach",
12340 scrollIntoView: "cursor",
12341 readOnly: true
12342 }, {
12343 name: "gotowordright",
12344 bindKey: bindKey("Ctrl-Right", "Option-Right"),
12345 exec: function(editor) { editor.navigateWordRight(); },
12346 multiSelectAction: "forEach",
12347 scrollIntoView: "cursor",
12348 readOnly: true
12349 }, {
12350 name: "selecttolineend",
12351 bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right|Shift-End|Ctrl-Shift-E"),
12352 exec: function(editor) { editor.getSelection().selectLineEnd(); },
12353 multiSelectAction: "forEach",
12354 scrollIntoView: "cursor",
12355 readOnly: true
12356 }, {
12357 name: "gotolineend",
12358 bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
12359 exec: function(editor) { editor.navigateLineEnd(); },
12360 multiSelectAction: "forEach",
12361 scrollIntoView: "cursor",
12362 readOnly: true
12363 }, {
12364 name: "selectright",
12365 bindKey: bindKey("Shift-Right", "Shift-Right"),
12366 exec: function(editor) { editor.getSelection().selectRight(); },
12367 multiSelectAction: "forEach",
12368 scrollIntoView: "cursor",
12369 readOnly: true
12370 }, {
12371 name: "gotoright",
12372 bindKey: bindKey("Right", "Right|Ctrl-F"),
12373 exec: function(editor, args) { editor.navigateRight(args.times); },
12374 multiSelectAction: "forEach",
12375 scrollIntoView: "cursor",
12376 readOnly: true
12377 }, {
12378 name: "selectpagedown",
12379 bindKey: "Shift-PageDown",
12380 exec: function(editor) { editor.selectPageDown(); },
12381 readOnly: true
12382 }, {
12383 name: "pagedown",
12384 bindKey: bindKey(null, "Option-PageDown"),
12385 exec: function(editor) { editor.scrollPageDown(); },
12386 readOnly: true
12387 }, {
12388 name: "gotopagedown",
12389 bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
12390 exec: function(editor) { editor.gotoPageDown(); },
12391 readOnly: true
12392 }, {
12393 name: "selectpageup",
12394 bindKey: "Shift-PageUp",
12395 exec: function(editor) { editor.selectPageUp(); },
12396 readOnly: true
12397 }, {
12398 name: "pageup",
12399 bindKey: bindKey(null, "Option-PageUp"),
12400 exec: function(editor) { editor.scrollPageUp(); },
12401 readOnly: true
12402 }, {
12403 name: "gotopageup",
12404 bindKey: "PageUp",
12405 exec: function(editor) { editor.gotoPageUp(); },
12406 readOnly: true
12407 }, {
12408 name: "scrollup",
12409 bindKey: bindKey("Ctrl-Up", null),
12410 exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
12411 readOnly: true
12412 }, {
12413 name: "scrolldown",
12414 bindKey: bindKey("Ctrl-Down", null),
12415 exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
12416 readOnly: true
12417 }, {
12418 name: "selectlinestart",
12419 bindKey: "Shift-Home",
12420 exec: function(editor) { editor.getSelection().selectLineStart(); },
12421 multiSelectAction: "forEach",
12422 scrollIntoView: "cursor",
12423 readOnly: true
12424 }, {
12425 name: "selectlineend",
12426 bindKey: "Shift-End",
12427 exec: function(editor) { editor.getSelection().selectLineEnd(); },
12428 multiSelectAction: "forEach",
12429 scrollIntoView: "cursor",
12430 readOnly: true
12431 }, {
12432 name: "togglerecording",
12433 bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
12434 exec: function(editor) { editor.commands.toggleRecording(editor); },
12435 readOnly: true
12436 }, {
12437 name: "replaymacro",
12438 bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
12439 exec: function(editor) { editor.commands.replay(editor); },
12440 readOnly: true
12441 }, {
12442 name: "jumptomatching",
12443 bindKey: bindKey("Ctrl-P", "Ctrl-P"),
12444 exec: function(editor) { editor.jumpToMatching(); },
12445 multiSelectAction: "forEach",
12446 scrollIntoView: "animate",
12447 readOnly: true
12448 }, {
12449 name: "selecttomatching",
12450 bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
12451 exec: function(editor) { editor.jumpToMatching(true); },
12452 multiSelectAction: "forEach",
12453 scrollIntoView: "animate",
12454 readOnly: true
12455 }, {
12456 name: "expandToMatching",
12457 bindKey: bindKey("Ctrl-Shift-M", "Ctrl-Shift-M"),
12458 exec: function(editor) { editor.jumpToMatching(true, true); },
12459 multiSelectAction: "forEach",
12460 scrollIntoView: "animate",
12461 readOnly: true
12462 }, {
12463 name: "passKeysToBrowser",
12464 bindKey: bindKey(null, null),
12465 exec: function() {},
12466 passEvent: true,
12467 readOnly: true
12468 }, {
12469 name: "copy",
12470 exec: function(editor) {
12471 },
12472 readOnly: true
12473 },
12474 {
12475 name: "cut",
12476 exec: function(editor) {
12477 var range = editor.getSelectionRange();
12478 editor._emit("cut", range);
12479
12480 if (!editor.selection.isEmpty()) {
12481 editor.session.remove(range);
12482 editor.clearSelection();
12483 }
12484 },
12485 scrollIntoView: "cursor",
12486 multiSelectAction: "forEach"
12487 }, {
12488 name: "paste",
12489 exec: function(editor, args) {
12490 editor.$handlePaste(args);
12491 },
12492 scrollIntoView: "cursor"
12493 }, {
12494 name: "removeline",
12495 bindKey: bindKey("Ctrl-D", "Command-D"),
12496 exec: function(editor) { editor.removeLines(); },
12497 scrollIntoView: "cursor",
12498 multiSelectAction: "forEachLine"
12499 }, {
12500 name: "duplicateSelection",
12501 bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
12502 exec: function(editor) { editor.duplicateSelection(); },
12503 scrollIntoView: "cursor",
12504 multiSelectAction: "forEach"
12505 }, {
12506 name: "sortlines",
12507 bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
12508 exec: function(editor) { editor.sortLines(); },
12509 scrollIntoView: "selection",
12510 multiSelectAction: "forEachLine"
12511 }, {
12512 name: "togglecomment",
12513 bindKey: bindKey("Ctrl-/", "Command-/"),
12514 exec: function(editor) { editor.toggleCommentLines(); },
12515 multiSelectAction: "forEachLine",
12516 scrollIntoView: "selectionPart"
12517 }, {
12518 name: "toggleBlockComment",
12519 bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
12520 exec: function(editor) { editor.toggleBlockComment(); },
12521 multiSelectAction: "forEach",
12522 scrollIntoView: "selectionPart"
12523 }, {
12524 name: "modifyNumberUp",
12525 bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
12526 exec: function(editor) { editor.modifyNumber(1); },
12527 scrollIntoView: "cursor",
12528 multiSelectAction: "forEach"
12529 }, {
12530 name: "modifyNumberDown",
12531 bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
12532 exec: function(editor) { editor.modifyNumber(-1); },
12533 scrollIntoView: "cursor",
12534 multiSelectAction: "forEach"
12535 }, {
12536 name: "replace",
12537 bindKey: bindKey("Ctrl-H", "Command-Option-F"),
12538 exec: function(editor) {
12539 config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true);});
12540 }
12541 }, {
12542 name: "undo",
12543 bindKey: bindKey("Ctrl-Z", "Command-Z"),
12544 exec: function(editor) { editor.undo(); }
12545 }, {
12546 name: "redo",
12547 bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
12548 exec: function(editor) { editor.redo(); }
12549 }, {
12550 name: "copylinesup",
12551 bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
12552 exec: function(editor) { editor.copyLinesUp(); },
12553 scrollIntoView: "cursor"
12554 }, {
12555 name: "movelinesup",
12556 bindKey: bindKey("Alt-Up", "Option-Up"),
12557 exec: function(editor) { editor.moveLinesUp(); },
12558 scrollIntoView: "cursor"
12559 }, {
12560 name: "copylinesdown",
12561 bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
12562 exec: function(editor) { editor.copyLinesDown(); },
12563 scrollIntoView: "cursor"
12564 }, {
12565 name: "movelinesdown",
12566 bindKey: bindKey("Alt-Down", "Option-Down"),
12567 exec: function(editor) { editor.moveLinesDown(); },
12568 scrollIntoView: "cursor"
12569 }, {
12570 name: "del",
12571 bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"),
12572 exec: function(editor) { editor.remove("right"); },
12573 multiSelectAction: "forEach",
12574 scrollIntoView: "cursor"
12575 }, {
12576 name: "backspace",
12577 bindKey: bindKey(
12578 "Shift-Backspace|Backspace",
12579 "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"
12580 ),
12581 exec: function(editor) { editor.remove("left"); },
12582 multiSelectAction: "forEach",
12583 scrollIntoView: "cursor"
12584 }, {
12585 name: "cut_or_delete",
12586 bindKey: bindKey("Shift-Delete", null),
12587 exec: function(editor) {
12588 if (editor.selection.isEmpty()) {
12589 editor.remove("left");
12590 } else {
12591 return false;
12592 }
12593 },
12594 multiSelectAction: "forEach",
12595 scrollIntoView: "cursor"
12596 }, {
12597 name: "removetolinestart",
12598 bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
12599 exec: function(editor) { editor.removeToLineStart(); },
12600 multiSelectAction: "forEach",
12601 scrollIntoView: "cursor"
12602 }, {
12603 name: "removetolineend",
12604 bindKey: bindKey("Alt-Delete", "Ctrl-K|Command-Delete"),
12605 exec: function(editor) { editor.removeToLineEnd(); },
12606 multiSelectAction: "forEach",
12607 scrollIntoView: "cursor"
12608 }, {
12609 name: "removetolinestarthard",
12610 bindKey: bindKey("Ctrl-Shift-Backspace", null),
12611 exec: function(editor) {
12612 var range = editor.selection.getRange();
12613 range.start.column = 0;
12614 editor.session.remove(range);
12615 },
12616 multiSelectAction: "forEach",
12617 scrollIntoView: "cursor"
12618 }, {
12619 name: "removetolineendhard",
12620 bindKey: bindKey("Ctrl-Shift-Delete", null),
12621 exec: function(editor) {
12622 var range = editor.selection.getRange();
12623 range.end.column = Number.MAX_VALUE;
12624 editor.session.remove(range);
12625 },
12626 multiSelectAction: "forEach",
12627 scrollIntoView: "cursor"
12628 }, {
12629 name: "removewordleft",
12630 bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
12631 exec: function(editor) { editor.removeWordLeft(); },
12632 multiSelectAction: "forEach",
12633 scrollIntoView: "cursor"
12634 }, {
12635 name: "removewordright",
12636 bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
12637 exec: function(editor) { editor.removeWordRight(); },
12638 multiSelectAction: "forEach",
12639 scrollIntoView: "cursor"
12640 }, {
12641 name: "outdent",
12642 bindKey: bindKey("Shift-Tab", "Shift-Tab"),
12643 exec: function(editor) { editor.blockOutdent(); },
12644 multiSelectAction: "forEach",
12645 scrollIntoView: "selectionPart"
12646 }, {
12647 name: "indent",
12648 bindKey: bindKey("Tab", "Tab"),
12649 exec: function(editor) { editor.indent(); },
12650 multiSelectAction: "forEach",
12651 scrollIntoView: "selectionPart"
12652 }, {
12653 name: "blockoutdent",
12654 bindKey: bindKey("Ctrl-[", "Ctrl-["),
12655 exec: function(editor) { editor.blockOutdent(); },
12656 multiSelectAction: "forEachLine",
12657 scrollIntoView: "selectionPart"
12658 }, {
12659 name: "blockindent",
12660 bindKey: bindKey("Ctrl-]", "Ctrl-]"),
12661 exec: function(editor) { editor.blockIndent(); },
12662 multiSelectAction: "forEachLine",
12663 scrollIntoView: "selectionPart"
12664 }, {
12665 name: "insertstring",
12666 exec: function(editor, str) { editor.insert(str); },
12667 multiSelectAction: "forEach",
12668 scrollIntoView: "cursor"
12669 }, {
12670 name: "inserttext",
12671 exec: function(editor, args) {
12672 editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
12673 },
12674 multiSelectAction: "forEach",
12675 scrollIntoView: "cursor"
12676 }, {
12677 name: "splitline",
12678 bindKey: bindKey(null, "Ctrl-O"),
12679 exec: function(editor) { editor.splitLine(); },
12680 multiSelectAction: "forEach",
12681 scrollIntoView: "cursor"
12682 }, {
12683 name: "transposeletters",
12684 bindKey: bindKey("Alt-Shift-X", "Ctrl-T"),
12685 exec: function(editor) { editor.transposeLetters(); },
12686 multiSelectAction: function(editor) {editor.transposeSelections(1); },
12687 scrollIntoView: "cursor"
12688 }, {
12689 name: "touppercase",
12690 bindKey: bindKey("Ctrl-U", "Ctrl-U"),
12691 exec: function(editor) { editor.toUpperCase(); },
12692 multiSelectAction: "forEach",
12693 scrollIntoView: "cursor"
12694 }, {
12695 name: "tolowercase",
12696 bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
12697 exec: function(editor) { editor.toLowerCase(); },
12698 multiSelectAction: "forEach",
12699 scrollIntoView: "cursor"
12700 }, {
12701 name: "expandtoline",
12702 bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"),
12703 exec: function(editor) {
12704 var range = editor.selection.getRange();
12705
12706 range.start.column = range.end.column = 0;
12707 range.end.row++;
12708 editor.selection.setRange(range, false);
12709 },
12710 multiSelectAction: "forEach",
12711 scrollIntoView: "cursor",
12712 readOnly: true
12713 }, {
12714 name: "joinlines",
12715 bindKey: bindKey(null, null),
12716 exec: function(editor) {
12717 var isBackwards = editor.selection.isBackwards();
12718 var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();
12719 var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();
12720 var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length;
12721 var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());
12722 var selectedCount = selectedText.replace(/\n\s*/, " ").length;
12723 var insertLine = editor.session.doc.getLine(selectionStart.row);
12724
12725 for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) {
12726 var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i)));
12727 if (curLine.length !== 0) {
12728 curLine = " " + curLine;
12729 }
12730 insertLine += curLine;
12731 }
12732
12733 if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {
12734 insertLine += editor.session.doc.getNewLineCharacter();
12735 }
12736
12737 editor.clearSelection();
12738 editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);
12739
12740 if (selectedCount > 0) {
12741 editor.selection.moveCursorTo(selectionStart.row, selectionStart.column);
12742 editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount);
12743 } else {
12744 firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol;
12745 editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol);
12746 }
12747 },
12748 multiSelectAction: "forEach",
12749 readOnly: true
12750 }, {
12751 name: "invertSelection",
12752 bindKey: bindKey(null, null),
12753 exec: function(editor) {
12754 var endRow = editor.session.doc.getLength() - 1;
12755 var endCol = editor.session.doc.getLine(endRow).length;
12756 var ranges = editor.selection.rangeList.ranges;
12757 var newRanges = [];
12758 if (ranges.length < 1) {
12759 ranges = [editor.selection.getRange()];
12760 }
12761
12762 for (var i = 0; i < ranges.length; i++) {
12763 if (i == (ranges.length - 1)) {
12764 if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) {
12765 newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol));
12766 }
12767 }
12768
12769 if (i === 0) {
12770 if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) {
12771 newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column));
12772 }
12773 } else {
12774 newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column));
12775 }
12776 }
12777
12778 editor.exitMultiSelectMode();
12779 editor.clearSelection();
12780
12781 for(var i = 0; i < newRanges.length; i++) {
12782 editor.selection.addRange(newRanges[i], false);
12783 }
12784 },
12785 readOnly: true,
12786 scrollIntoView: "none"
12787 }];
12788
12789 });
12790
12791 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(require, exports, module) {
12792 "use strict";
12793
12794 require("./lib/fixoldbrowsers");
12795
12796 var oop = require("./lib/oop");
12797 var dom = require("./lib/dom");
12798 var lang = require("./lib/lang");
12799 var useragent = require("./lib/useragent");
12800 var TextInput = require("./keyboard/textinput").TextInput;
12801 var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
12802 var FoldHandler = require("./mouse/fold_handler").FoldHandler;
12803 var KeyBinding = require("./keyboard/keybinding").KeyBinding;
12804 var EditSession = require("./edit_session").EditSession;
12805 var Search = require("./search").Search;
12806 var Range = require("./range").Range;
12807 var EventEmitter = require("./lib/event_emitter").EventEmitter;
12808 var CommandManager = require("./commands/command_manager").CommandManager;
12809 var defaultCommands = require("./commands/default_commands").commands;
12810 var config = require("./config");
12811 var TokenIterator = require("./token_iterator").TokenIterator;
12812 var Editor = function(renderer, session) {
12813 var container = renderer.getContainerElement();
12814 this.container = container;
12815 this.renderer = renderer;
12816 this.id = "editor" + (++Editor.$uid);
12817
12818 this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
12819 if (typeof document == "object") {
12820 this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
12821 this.renderer.textarea = this.textInput.getElement();
12822 this.$mouseHandler = new MouseHandler(this);
12823 new FoldHandler(this);
12824 }
12825
12826 this.keyBinding = new KeyBinding(this);
12827
12828 this.$blockScrolling = 0;
12829 this.$search = new Search().set({
12830 wrap: true
12831 });
12832
12833 this.$historyTracker = this.$historyTracker.bind(this);
12834 this.commands.on("exec", this.$historyTracker);
12835
12836 this.$initOperationListeners();
12837
12838 this._$emitInputEvent = lang.delayedCall(function() {
12839 this._signal("input", {});
12840 if (this.session && this.session.bgTokenizer)
12841 this.session.bgTokenizer.scheduleStart();
12842 }.bind(this));
12843
12844 this.on("change", function(_, _self) {
12845 _self._$emitInputEvent.schedule(31);
12846 });
12847
12848 this.setSession(session || new EditSession(""));
12849 config.resetOptions(this);
12850 config._signal("editor", this);
12851 };
12852
12853 Editor.$uid = 0;
12854
12855 (function(){
12856
12857 oop.implement(this, EventEmitter);
12858
12859 this.$initOperationListeners = function() {
12860 function last(a) {return a[a.length - 1];}
12861
12862 this.selections = [];
12863 this.commands.on("exec", this.startOperation.bind(this), true);
12864 this.commands.on("afterExec", this.endOperation.bind(this), true);
12865
12866 this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
12867
12868 this.on("change", function() {
12869 this.curOp || this.startOperation();
12870 this.curOp.docChanged = true;
12871 }.bind(this), true);
12872
12873 this.on("changeSelection", function() {
12874 this.curOp || this.startOperation();
12875 this.curOp.selectionChanged = true;
12876 }.bind(this), true);
12877 };
12878
12879 this.curOp = null;
12880 this.prevOp = {};
12881 this.startOperation = function(commadEvent) {
12882 if (this.curOp) {
12883 if (!commadEvent || this.curOp.command)
12884 return;
12885 this.prevOp = this.curOp;
12886 }
12887 if (!commadEvent) {
12888 this.previousCommand = null;
12889 commadEvent = {};
12890 }
12891
12892 this.$opResetTimer.schedule();
12893 this.curOp = {
12894 command: commadEvent.command || {},
12895 args: commadEvent.args,
12896 scrollTop: this.renderer.scrollTop
12897 };
12898 if (this.curOp.command.name && this.curOp.command.scrollIntoView !== undefined)
12899 this.$blockScrolling++;
12900 };
12901
12902 this.endOperation = function(e) {
12903 if (this.curOp) {
12904 if (e && e.returnValue === false)
12905 return this.curOp = null;
12906 this._signal("beforeEndOperation");
12907 var command = this.curOp.command;
12908 if (command.name && this.$blockScrolling > 0)
12909 this.$blockScrolling--;
12910 var scrollIntoView = command && command.scrollIntoView;
12911 if (scrollIntoView) {
12912 switch (scrollIntoView) {
12913 case "center-animate":
12914 scrollIntoView = "animate";
12915 case "center":
12916 this.renderer.scrollCursorIntoView(null, 0.5);
12917 break;
12918 case "animate":
12919 case "cursor":
12920 this.renderer.scrollCursorIntoView();
12921 break;
12922 case "selectionPart":
12923 var range = this.selection.getRange();
12924 var config = this.renderer.layerConfig;
12925 if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
12926 this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
12927 }
12928 break;
12929 default:
12930 break;
12931 }
12932 if (scrollIntoView == "animate")
12933 this.renderer.animateScrolling(this.curOp.scrollTop);
12934 }
12935
12936 this.prevOp = this.curOp;
12937 this.curOp = null;
12938 }
12939 };
12940 this.$mergeableCommands = ["backspace", "del", "insertstring"];
12941 this.$historyTracker = function(e) {
12942 if (!this.$mergeUndoDeltas)
12943 return;
12944
12945 var prev = this.prevOp;
12946 var mergeableCommands = this.$mergeableCommands;
12947 var shouldMerge = prev.command && (e.command.name == prev.command.name);
12948 if (e.command.name == "insertstring") {
12949 var text = e.args;
12950 if (this.mergeNextCommand === undefined)
12951 this.mergeNextCommand = true;
12952
12953 shouldMerge = shouldMerge
12954 && this.mergeNextCommand // previous command allows to coalesce with
12955 && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
12956
12957 this.mergeNextCommand = true;
12958 } else {
12959 shouldMerge = shouldMerge
12960 && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
12961 }
12962
12963 if (
12964 this.$mergeUndoDeltas != "always"
12965 && Date.now() - this.sequenceStartTime > 2000
12966 ) {
12967 shouldMerge = false; // the sequence is too long
12968 }
12969
12970 if (shouldMerge)
12971 this.session.mergeUndoDeltas = true;
12972 else if (mergeableCommands.indexOf(e.command.name) !== -1)
12973 this.sequenceStartTime = Date.now();
12974 };
12975 this.setKeyboardHandler = function(keyboardHandler, cb) {
12976 if (keyboardHandler && typeof keyboardHandler === "string") {
12977 this.$keybindingId = keyboardHandler;
12978 var _self = this;
12979 config.loadModule(["keybinding", keyboardHandler], function(module) {
12980 if (_self.$keybindingId == keyboardHandler)
12981 _self.keyBinding.setKeyboardHandler(module && module.handler);
12982 cb && cb();
12983 });
12984 } else {
12985 this.$keybindingId = null;
12986 this.keyBinding.setKeyboardHandler(keyboardHandler);
12987 cb && cb();
12988 }
12989 };
12990 this.getKeyboardHandler = function() {
12991 return this.keyBinding.getKeyboardHandler();
12992 };
12993 this.setSession = function(session) {
12994 if (this.session == session)
12995 return;
12996 if (this.curOp) this.endOperation();
12997 this.curOp = {};
12998
12999 var oldSession = this.session;
13000 if (oldSession) {
13001 this.session.off("change", this.$onDocumentChange);
13002 this.session.off("changeMode", this.$onChangeMode);
13003 this.session.off("tokenizerUpdate", this.$onTokenizerUpdate);
13004 this.session.off("changeTabSize", this.$onChangeTabSize);
13005 this.session.off("changeWrapLimit", this.$onChangeWrapLimit);
13006 this.session.off("changeWrapMode", this.$onChangeWrapMode);
13007 this.session.off("changeFold", this.$onChangeFold);
13008 this.session.off("changeFrontMarker", this.$onChangeFrontMarker);
13009 this.session.off("changeBackMarker", this.$onChangeBackMarker);
13010 this.session.off("changeBreakpoint", this.$onChangeBreakpoint);
13011 this.session.off("changeAnnotation", this.$onChangeAnnotation);
13012 this.session.off("changeOverwrite", this.$onCursorChange);
13013 this.session.off("changeScrollTop", this.$onScrollTopChange);
13014 this.session.off("changeScrollLeft", this.$onScrollLeftChange);
13015
13016 var selection = this.session.getSelection();
13017 selection.off("changeCursor", this.$onCursorChange);
13018 selection.off("changeSelection", this.$onSelectionChange);
13019 }
13020
13021 this.session = session;
13022 if (session) {
13023 this.$onDocumentChange = this.onDocumentChange.bind(this);
13024 session.on("change", this.$onDocumentChange);
13025 this.renderer.setSession(session);
13026
13027 this.$onChangeMode = this.onChangeMode.bind(this);
13028 session.on("changeMode", this.$onChangeMode);
13029
13030 this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
13031 session.on("tokenizerUpdate", this.$onTokenizerUpdate);
13032
13033 this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
13034 session.on("changeTabSize", this.$onChangeTabSize);
13035
13036 this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
13037 session.on("changeWrapLimit", this.$onChangeWrapLimit);
13038
13039 this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
13040 session.on("changeWrapMode", this.$onChangeWrapMode);
13041
13042 this.$onChangeFold = this.onChangeFold.bind(this);
13043 session.on("changeFold", this.$onChangeFold);
13044
13045 this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
13046 this.session.on("changeFrontMarker", this.$onChangeFrontMarker);
13047
13048 this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
13049 this.session.on("changeBackMarker", this.$onChangeBackMarker);
13050
13051 this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
13052 this.session.on("changeBreakpoint", this.$onChangeBreakpoint);
13053
13054 this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
13055 this.session.on("changeAnnotation", this.$onChangeAnnotation);
13056
13057 this.$onCursorChange = this.onCursorChange.bind(this);
13058 this.session.on("changeOverwrite", this.$onCursorChange);
13059
13060 this.$onScrollTopChange = this.onScrollTopChange.bind(this);
13061 this.session.on("changeScrollTop", this.$onScrollTopChange);
13062
13063 this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
13064 this.session.on("changeScrollLeft", this.$onScrollLeftChange);
13065
13066 this.selection = session.getSelection();
13067 this.selection.on("changeCursor", this.$onCursorChange);
13068
13069 this.$onSelectionChange = this.onSelectionChange.bind(this);
13070 this.selection.on("changeSelection", this.$onSelectionChange);
13071
13072 this.onChangeMode();
13073
13074 this.$blockScrolling += 1;
13075 this.onCursorChange();
13076 this.$blockScrolling -= 1;
13077
13078 this.onScrollTopChange();
13079 this.onScrollLeftChange();
13080 this.onSelectionChange();
13081 this.onChangeFrontMarker();
13082 this.onChangeBackMarker();
13083 this.onChangeBreakpoint();
13084 this.onChangeAnnotation();
13085 this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
13086 this.renderer.updateFull();
13087 } else {
13088 this.selection = null;
13089 this.renderer.setSession(session);
13090 }
13091
13092 this._signal("changeSession", {
13093 session: session,
13094 oldSession: oldSession
13095 });
13096
13097 this.curOp = null;
13098
13099 oldSession && oldSession._signal("changeEditor", {oldEditor: this});
13100 session && session._signal("changeEditor", {editor: this});
13101
13102 if (session && session.bgTokenizer)
13103 session.bgTokenizer.scheduleStart();
13104 };
13105 this.getSession = function() {
13106 return this.session;
13107 };
13108 this.setValue = function(val, cursorPos) {
13109 this.session.doc.setValue(val);
13110
13111 if (!cursorPos)
13112 this.selectAll();
13113 else if (cursorPos == 1)
13114 this.navigateFileEnd();
13115 else if (cursorPos == -1)
13116 this.navigateFileStart();
13117
13118 return val;
13119 };
13120 this.getValue = function() {
13121 return this.session.getValue();
13122 };
13123 this.getSelection = function() {
13124 return this.selection;
13125 };
13126 this.resize = function(force) {
13127 this.renderer.onResize(force);
13128 };
13129 this.setTheme = function(theme, cb) {
13130 this.renderer.setTheme(theme, cb);
13131 };
13132 this.getTheme = function() {
13133 return this.renderer.getTheme();
13134 };
13135 this.setStyle = function(style) {
13136 this.renderer.setStyle(style);
13137 };
13138 this.unsetStyle = function(style) {
13139 this.renderer.unsetStyle(style);
13140 };
13141 this.getFontSize = function () {
13142 return this.getOption("fontSize") ||
13143 dom.computedStyle(this.container, "fontSize");
13144 };
13145 this.setFontSize = function(size) {
13146 this.setOption("fontSize", size);
13147 };
13148
13149 this.$highlightBrackets = function() {
13150 if (this.session.$bracketHighlight) {
13151 this.session.removeMarker(this.session.$bracketHighlight);
13152 this.session.$bracketHighlight = null;
13153 }
13154
13155 if (this.$highlightPending) {
13156 return;
13157 }
13158 var self = this;
13159 this.$highlightPending = true;
13160 setTimeout(function() {
13161 self.$highlightPending = false;
13162 var session = self.session;
13163 if (!session || !session.bgTokenizer) return;
13164 var pos = session.findMatchingBracket(self.getCursorPosition());
13165 if (pos) {
13166 var range = new Range(pos.row, pos.column, pos.row, pos.column + 1);
13167 } else if (session.$mode.getMatching) {
13168 var range = session.$mode.getMatching(self.session);
13169 }
13170 if (range)
13171 session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text");
13172 }, 50);
13173 };
13174 this.$highlightTags = function() {
13175 if (this.$highlightTagPending)
13176 return;
13177 var self = this;
13178 this.$highlightTagPending = true;
13179 setTimeout(function() {
13180 self.$highlightTagPending = false;
13181
13182 var session = self.session;
13183 if (!session || !session.bgTokenizer) return;
13184
13185 var pos = self.getCursorPosition();
13186 var iterator = new TokenIterator(self.session, pos.row, pos.column);
13187 var token = iterator.getCurrentToken();
13188
13189 if (!token || !/\b(?:tag-open|tag-name)/.test(token.type)) {
13190 session.removeMarker(session.$tagHighlight);
13191 session.$tagHighlight = null;
13192 return;
13193 }
13194
13195 if (token.type.indexOf("tag-open") != -1) {
13196 token = iterator.stepForward();
13197 if (!token)
13198 return;
13199 }
13200
13201 var tag = token.value;
13202 var depth = 0;
13203 var prevToken = iterator.stepBackward();
13204
13205 if (prevToken.value == '<'){
13206 do {
13207 prevToken = token;
13208 token = iterator.stepForward();
13209
13210 if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
13211 if (prevToken.value === '<'){
13212 depth++;
13213 } else if (prevToken.value === '</'){
13214 depth--;
13215 }
13216 }
13217
13218 } while (token && depth >= 0);
13219 } else {
13220 do {
13221 token = prevToken;
13222 prevToken = iterator.stepBackward();
13223
13224 if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
13225 if (prevToken.value === '<') {
13226 depth++;
13227 } else if (prevToken.value === '</') {
13228 depth--;
13229 }
13230 }
13231 } while (prevToken && depth <= 0);
13232 iterator.stepForward();
13233 }
13234
13235 if (!token) {
13236 session.removeMarker(session.$tagHighlight);
13237 session.$tagHighlight = null;
13238 return;
13239 }
13240
13241 var row = iterator.getCurrentTokenRow();
13242 var column = iterator.getCurrentTokenColumn();
13243 var range = new Range(row, column, row, column+token.value.length);
13244 var sbm = session.$backMarkers[session.$tagHighlight];
13245 if (session.$tagHighlight && sbm != undefined && range.compareRange(sbm.range) !== 0) {
13246 session.removeMarker(session.$tagHighlight);
13247 session.$tagHighlight = null;
13248 }
13249
13250 if (range && !session.$tagHighlight)
13251 session.$tagHighlight = session.addMarker(range, "ace_bracket", "text");
13252 }, 50);
13253 };
13254 this.focus = function() {
13255 var _self = this;
13256 setTimeout(function() {
13257 _self.textInput.focus();
13258 });
13259 this.textInput.focus();
13260 };
13261 this.isFocused = function() {
13262 return this.textInput.isFocused();
13263 };
13264 this.blur = function() {
13265 this.textInput.blur();
13266 };
13267 this.onFocus = function(e) {
13268 if (this.$isFocused)
13269 return;
13270 this.$isFocused = true;
13271 this.renderer.showCursor();
13272 this.renderer.visualizeFocus();
13273 this._emit("focus", e);
13274 };
13275 this.onBlur = function(e) {
13276 if (!this.$isFocused)
13277 return;
13278 this.$isFocused = false;
13279 this.renderer.hideCursor();
13280 this.renderer.visualizeBlur();
13281 this._emit("blur", e);
13282 };
13283
13284 this.$cursorChange = function() {
13285 this.renderer.updateCursor();
13286 };
13287 this.onDocumentChange = function(delta) {
13288 var wrap = this.session.$useWrapMode;
13289 var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);
13290 this.renderer.updateLines(delta.start.row, lastRow, wrap);
13291
13292 this._signal("change", delta);
13293 this.$cursorChange();
13294 this.$updateHighlightActiveLine();
13295 };
13296
13297 this.onTokenizerUpdate = function(e) {
13298 var rows = e.data;
13299 this.renderer.updateLines(rows.first, rows.last);
13300 };
13301
13302
13303 this.onScrollTopChange = function() {
13304 this.renderer.scrollToY(this.session.getScrollTop());
13305 };
13306
13307 this.onScrollLeftChange = function() {
13308 this.renderer.scrollToX(this.session.getScrollLeft());
13309 };
13310 this.onCursorChange = function() {
13311 this.$cursorChange();
13312
13313 if (!this.$blockScrolling) {
13314 config.warn("Automatically scrolling cursor into view after selection change",
13315 "this will be disabled in the next version",
13316 "set editor.$blockScrolling = Infinity to disable this message"
13317 );
13318 this.renderer.scrollCursorIntoView();
13319 }
13320
13321 this.$highlightBrackets();
13322 this.$highlightTags();
13323 this.$updateHighlightActiveLine();
13324 this._signal("changeSelection");
13325 };
13326
13327 this.$updateHighlightActiveLine = function() {
13328 var session = this.getSession();
13329
13330 var highlight;
13331 if (this.$highlightActiveLine) {
13332 if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
13333 highlight = this.getCursorPosition();
13334 if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
13335 highlight = false;
13336 }
13337
13338 if (session.$highlightLineMarker && !highlight) {
13339 session.removeMarker(session.$highlightLineMarker.id);
13340 session.$highlightLineMarker = null;
13341 } else if (!session.$highlightLineMarker && highlight) {
13342 var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
13343 range.id = session.addMarker(range, "ace_active-line", "screenLine");
13344 session.$highlightLineMarker = range;
13345 } else if (highlight) {
13346 session.$highlightLineMarker.start.row = highlight.row;
13347 session.$highlightLineMarker.end.row = highlight.row;
13348 session.$highlightLineMarker.start.column = highlight.column;
13349 session._signal("changeBackMarker");
13350 }
13351 };
13352
13353 this.onSelectionChange = function(e) {
13354 var session = this.session;
13355
13356 if (session.$selectionMarker) {
13357 session.removeMarker(session.$selectionMarker);
13358 }
13359 session.$selectionMarker = null;
13360
13361 if (!this.selection.isEmpty()) {
13362 var range = this.selection.getRange();
13363 var style = this.getSelectionStyle();
13364 session.$selectionMarker = session.addMarker(range, "ace_selection", style);
13365 } else {
13366 this.$updateHighlightActiveLine();
13367 }
13368
13369 var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
13370 this.session.highlight(re);
13371
13372 this._signal("changeSelection");
13373 };
13374
13375 this.$getSelectionHighLightRegexp = function() {
13376 var session = this.session;
13377
13378 var selection = this.getSelectionRange();
13379 if (selection.isEmpty() || selection.isMultiLine())
13380 return;
13381
13382 var startOuter = selection.start.column - 1;
13383 var endOuter = selection.end.column + 1;
13384 var line = session.getLine(selection.start.row);
13385 var lineCols = line.length;
13386 var needle = line.substring(Math.max(startOuter, 0),
13387 Math.min(endOuter, lineCols));
13388 if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
13389 (endOuter <= lineCols && /[\w\d]$/.test(needle)))
13390 return;
13391
13392 needle = line.substring(selection.start.column, selection.end.column);
13393 if (!/^[\w\d]+$/.test(needle))
13394 return;
13395
13396 var re = this.$search.$assembleRegExp({
13397 wholeWord: true,
13398 caseSensitive: true,
13399 needle: needle
13400 });
13401
13402 return re;
13403 };
13404
13405
13406 this.onChangeFrontMarker = function() {
13407 this.renderer.updateFrontMarkers();
13408 };
13409
13410 this.onChangeBackMarker = function() {
13411 this.renderer.updateBackMarkers();
13412 };
13413
13414
13415 this.onChangeBreakpoint = function() {
13416 this.renderer.updateBreakpoints();
13417 };
13418
13419 this.onChangeAnnotation = function() {
13420 this.renderer.setAnnotations(this.session.getAnnotations());
13421 };
13422
13423
13424 this.onChangeMode = function(e) {
13425 this.renderer.updateText();
13426 this._emit("changeMode", e);
13427 };
13428
13429
13430 this.onChangeWrapLimit = function() {
13431 this.renderer.updateFull();
13432 };
13433
13434 this.onChangeWrapMode = function() {
13435 this.renderer.onResize(true);
13436 };
13437
13438
13439 this.onChangeFold = function() {
13440 this.$updateHighlightActiveLine();
13441 this.renderer.updateFull();
13442 };
13443 this.getSelectedText = function() {
13444 return this.session.getTextRange(this.getSelectionRange());
13445 };
13446 this.getCopyText = function() {
13447 var text = this.getSelectedText();
13448 this._signal("copy", text);
13449 return text;
13450 };
13451 this.onCopy = function() {
13452 this.commands.exec("copy", this);
13453 };
13454 this.onCut = function() {
13455 this.commands.exec("cut", this);
13456 };
13457 this.onPaste = function(text, event) {
13458 var e = {text: text, event: event};
13459 this.commands.exec("paste", this, e);
13460 };
13461
13462 this.$handlePaste = function(e) {
13463 if (typeof e == "string")
13464 e = {text: e};
13465 this._signal("paste", e);
13466 var text = e.text;
13467 if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
13468 this.insert(text);
13469 } else {
13470 var lines = text.split(/\r\n|\r|\n/);
13471 var ranges = this.selection.rangeList.ranges;
13472
13473 if (lines.length > ranges.length || lines.length < 2 || !lines[1])
13474 return this.commands.exec("insertstring", this, text);
13475
13476 for (var i = ranges.length; i--;) {
13477 var range = ranges[i];
13478 if (!range.isEmpty())
13479 this.session.remove(range);
13480
13481 this.session.insert(range.start, lines[i]);
13482 }
13483 }
13484 };
13485
13486 this.execCommand = function(command, args) {
13487 return this.commands.exec(command, this, args);
13488 };
13489 this.insert = function(text, pasted) {
13490 var session = this.session;
13491 var mode = session.getMode();
13492 var cursor = this.getCursorPosition();
13493
13494 if (this.getBehavioursEnabled() && !pasted) {
13495 var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
13496 if (transform) {
13497 if (text !== transform.text) {
13498 this.session.mergeUndoDeltas = false;
13499 this.$mergeNextCommand = false;
13500 }
13501 text = transform.text;
13502
13503 }
13504 }
13505
13506 if (text == "\t")
13507 text = this.session.getTabString();
13508 if (!this.selection.isEmpty()) {
13509 var range = this.getSelectionRange();
13510 cursor = this.session.remove(range);
13511 this.clearSelection();
13512 }
13513 else if (this.session.getOverwrite() && text.indexOf("\n") == -1) {
13514 var range = new Range.fromPoints(cursor, cursor);
13515 range.end.column += text.length;
13516 this.session.remove(range);
13517 }
13518
13519 if (text == "\n" || text == "\r\n") {
13520 var line = session.getLine(cursor.row);
13521 if (cursor.column > line.search(/\S|$/)) {
13522 var d = line.substr(cursor.column).search(/\S|$/);
13523 session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
13524 }
13525 }
13526 this.clearSelection();
13527
13528 var start = cursor.column;
13529 var lineState = session.getState(cursor.row);
13530 var line = session.getLine(cursor.row);
13531 var shouldOutdent = mode.checkOutdent(lineState, line, text);
13532 var end = session.insert(cursor, text);
13533
13534 if (transform && transform.selection) {
13535 if (transform.selection.length == 2) { // Transform relative to the current column
13536 this.selection.setSelectionRange(
13537 new Range(cursor.row, start + transform.selection[0],
13538 cursor.row, start + transform.selection[1]));
13539 } else { // Transform relative to the current row.
13540 this.selection.setSelectionRange(
13541 new Range(cursor.row + transform.selection[0],
13542 transform.selection[1],
13543 cursor.row + transform.selection[2],
13544 transform.selection[3]));
13545 }
13546 }
13547
13548 if (session.getDocument().isNewLine(text)) {
13549 var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
13550
13551 session.insert({row: cursor.row+1, column: 0}, lineIndent);
13552 }
13553 if (shouldOutdent)
13554 mode.autoOutdent(lineState, session, cursor.row);
13555 };
13556
13557 this.onTextInput = function(text) {
13558 this.keyBinding.onTextInput(text);
13559 };
13560
13561 this.onCommandKey = function(e, hashId, keyCode) {
13562 this.keyBinding.onCommandKey(e, hashId, keyCode);
13563 };
13564 this.setOverwrite = function(overwrite) {
13565 this.session.setOverwrite(overwrite);
13566 };
13567 this.getOverwrite = function() {
13568 return this.session.getOverwrite();
13569 };
13570 this.toggleOverwrite = function() {
13571 this.session.toggleOverwrite();
13572 };
13573 this.setScrollSpeed = function(speed) {
13574 this.setOption("scrollSpeed", speed);
13575 };
13576 this.getScrollSpeed = function() {
13577 return this.getOption("scrollSpeed");
13578 };
13579 this.setDragDelay = function(dragDelay) {
13580 this.setOption("dragDelay", dragDelay);
13581 };
13582 this.getDragDelay = function() {
13583 return this.getOption("dragDelay");
13584 };
13585 this.setSelectionStyle = function(val) {
13586 this.setOption("selectionStyle", val);
13587 };
13588 this.getSelectionStyle = function() {
13589 return this.getOption("selectionStyle");
13590 };
13591 this.setHighlightActiveLine = function(shouldHighlight) {
13592 this.setOption("highlightActiveLine", shouldHighlight);
13593 };
13594 this.getHighlightActiveLine = function() {
13595 return this.getOption("highlightActiveLine");
13596 };
13597 this.setHighlightGutterLine = function(shouldHighlight) {
13598 this.setOption("highlightGutterLine", shouldHighlight);
13599 };
13600
13601 this.getHighlightGutterLine = function() {
13602 return this.getOption("highlightGutterLine");
13603 };
13604 this.setHighlightSelectedWord = function(shouldHighlight) {
13605 this.setOption("highlightSelectedWord", shouldHighlight);
13606 };
13607 this.getHighlightSelectedWord = function() {
13608 return this.$highlightSelectedWord;
13609 };
13610
13611 this.setAnimatedScroll = function(shouldAnimate){
13612 this.renderer.setAnimatedScroll(shouldAnimate);
13613 };
13614
13615 this.getAnimatedScroll = function(){
13616 return this.renderer.getAnimatedScroll();
13617 };
13618 this.setShowInvisibles = function(showInvisibles) {
13619 this.renderer.setShowInvisibles(showInvisibles);
13620 };
13621 this.getShowInvisibles = function() {
13622 return this.renderer.getShowInvisibles();
13623 };
13624
13625 this.setDisplayIndentGuides = function(display) {
13626 this.renderer.setDisplayIndentGuides(display);
13627 };
13628
13629 this.getDisplayIndentGuides = function() {
13630 return this.renderer.getDisplayIndentGuides();
13631 };
13632 this.setShowPrintMargin = function(showPrintMargin) {
13633 this.renderer.setShowPrintMargin(showPrintMargin);
13634 };
13635 this.getShowPrintMargin = function() {
13636 return this.renderer.getShowPrintMargin();
13637 };
13638 this.setPrintMarginColumn = function(showPrintMargin) {
13639 this.renderer.setPrintMarginColumn(showPrintMargin);
13640 };
13641 this.getPrintMarginColumn = function() {
13642 return this.renderer.getPrintMarginColumn();
13643 };
13644 this.setReadOnly = function(readOnly) {
13645 this.setOption("readOnly", readOnly);
13646 };
13647 this.getReadOnly = function() {
13648 return this.getOption("readOnly");
13649 };
13650 this.setBehavioursEnabled = function (enabled) {
13651 this.setOption("behavioursEnabled", enabled);
13652 };
13653 this.getBehavioursEnabled = function () {
13654 return this.getOption("behavioursEnabled");
13655 };
13656 this.setWrapBehavioursEnabled = function (enabled) {
13657 this.setOption("wrapBehavioursEnabled", enabled);
13658 };
13659 this.getWrapBehavioursEnabled = function () {
13660 return this.getOption("wrapBehavioursEnabled");
13661 };
13662 this.setShowFoldWidgets = function(show) {
13663 this.setOption("showFoldWidgets", show);
13664
13665 };
13666 this.getShowFoldWidgets = function() {
13667 return this.getOption("showFoldWidgets");
13668 };
13669
13670 this.setFadeFoldWidgets = function(fade) {
13671 this.setOption("fadeFoldWidgets", fade);
13672 };
13673
13674 this.getFadeFoldWidgets = function() {
13675 return this.getOption("fadeFoldWidgets");
13676 };
13677 this.remove = function(dir) {
13678 if (this.selection.isEmpty()){
13679 if (dir == "left")
13680 this.selection.selectLeft();
13681 else
13682 this.selection.selectRight();
13683 }
13684
13685 var range = this.getSelectionRange();
13686 if (this.getBehavioursEnabled()) {
13687 var session = this.session;
13688 var state = session.getState(range.start.row);
13689 var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
13690
13691 if (range.end.column === 0) {
13692 var text = session.getTextRange(range);
13693 if (text[text.length - 1] == "\n") {
13694 var line = session.getLine(range.end.row);
13695 if (/^\s+$/.test(line)) {
13696 range.end.column = line.length;
13697 }
13698 }
13699 }
13700 if (new_range)
13701 range = new_range;
13702 }
13703
13704 this.session.remove(range);
13705 this.clearSelection();
13706 };
13707 this.removeWordRight = function() {
13708 if (this.selection.isEmpty())
13709 this.selection.selectWordRight();
13710
13711 this.session.remove(this.getSelectionRange());
13712 this.clearSelection();
13713 };
13714 this.removeWordLeft = function() {
13715 if (this.selection.isEmpty())
13716 this.selection.selectWordLeft();
13717
13718 this.session.remove(this.getSelectionRange());
13719 this.clearSelection();
13720 };
13721 this.removeToLineStart = function() {
13722 if (this.selection.isEmpty())
13723 this.selection.selectLineStart();
13724
13725 this.session.remove(this.getSelectionRange());
13726 this.clearSelection();
13727 };
13728 this.removeToLineEnd = function() {
13729 if (this.selection.isEmpty())
13730 this.selection.selectLineEnd();
13731
13732 var range = this.getSelectionRange();
13733 if (range.start.column == range.end.column && range.start.row == range.end.row) {
13734 range.end.column = 0;
13735 range.end.row++;
13736 }
13737
13738 this.session.remove(range);
13739 this.clearSelection();
13740 };
13741 this.splitLine = function() {
13742 if (!this.selection.isEmpty()) {
13743 this.session.remove(this.getSelectionRange());
13744 this.clearSelection();
13745 }
13746
13747 var cursor = this.getCursorPosition();
13748 this.insert("\n");
13749 this.moveCursorToPosition(cursor);
13750 };
13751 this.transposeLetters = function() {
13752 if (!this.selection.isEmpty()) {
13753 return;
13754 }
13755
13756 var cursor = this.getCursorPosition();
13757 var column = cursor.column;
13758 if (column === 0)
13759 return;
13760
13761 var line = this.session.getLine(cursor.row);
13762 var swap, range;
13763 if (column < line.length) {
13764 swap = line.charAt(column) + line.charAt(column-1);
13765 range = new Range(cursor.row, column-1, cursor.row, column+1);
13766 }
13767 else {
13768 swap = line.charAt(column-1) + line.charAt(column-2);
13769 range = new Range(cursor.row, column-2, cursor.row, column);
13770 }
13771 this.session.replace(range, swap);
13772 this.session.selection.moveToPosition(range.end);
13773 };
13774 this.toLowerCase = function() {
13775 var originalRange = this.getSelectionRange();
13776 if (this.selection.isEmpty()) {
13777 this.selection.selectWord();
13778 }
13779
13780 var range = this.getSelectionRange();
13781 var text = this.session.getTextRange(range);
13782 this.session.replace(range, text.toLowerCase());
13783 this.selection.setSelectionRange(originalRange);
13784 };
13785 this.toUpperCase = function() {
13786 var originalRange = this.getSelectionRange();
13787 if (this.selection.isEmpty()) {
13788 this.selection.selectWord();
13789 }
13790
13791 var range = this.getSelectionRange();
13792 var text = this.session.getTextRange(range);
13793 this.session.replace(range, text.toUpperCase());
13794 this.selection.setSelectionRange(originalRange);
13795 };
13796 this.indent = function() {
13797 var session = this.session;
13798 var range = this.getSelectionRange();
13799
13800 if (range.start.row < range.end.row) {
13801 var rows = this.$getSelectedRows();
13802 session.indentRows(rows.first, rows.last, "\t");
13803 return;
13804 } else if (range.start.column < range.end.column) {
13805 var text = session.getTextRange(range);
13806 if (!/^\s+$/.test(text)) {
13807 var rows = this.$getSelectedRows();
13808 session.indentRows(rows.first, rows.last, "\t");
13809 return;
13810 }
13811 }
13812
13813 var line = session.getLine(range.start.row);
13814 var position = range.start;
13815 var size = session.getTabSize();
13816 var column = session.documentToScreenColumn(position.row, position.column);
13817
13818 if (this.session.getUseSoftTabs()) {
13819 var count = (size - column % size);
13820 var indentString = lang.stringRepeat(" ", count);
13821 } else {
13822 var count = column % size;
13823 while (line[range.start.column - 1] == " " && count) {
13824 range.start.column--;
13825 count--;
13826 }
13827 this.selection.setSelectionRange(range);
13828 indentString = "\t";
13829 }
13830 return this.insert(indentString);
13831 };
13832 this.blockIndent = function() {
13833 var rows = this.$getSelectedRows();
13834 this.session.indentRows(rows.first, rows.last, "\t");
13835 };
13836 this.blockOutdent = function() {
13837 var selection = this.session.getSelection();
13838 this.session.outdentRows(selection.getRange());
13839 };
13840 this.sortLines = function() {
13841 var rows = this.$getSelectedRows();
13842 var session = this.session;
13843
13844 var lines = [];
13845 for (var i = rows.first; i <= rows.last; i++)
13846 lines.push(session.getLine(i));
13847
13848 lines.sort(function(a, b) {
13849 if (a.toLowerCase() < b.toLowerCase()) return -1;
13850 if (a.toLowerCase() > b.toLowerCase()) return 1;
13851 return 0;
13852 });
13853
13854 var deleteRange = new Range(0, 0, 0, 0);
13855 for (var i = rows.first; i <= rows.last; i++) {
13856 var line = session.getLine(i);
13857 deleteRange.start.row = i;
13858 deleteRange.end.row = i;
13859 deleteRange.end.column = line.length;
13860 session.replace(deleteRange, lines[i-rows.first]);
13861 }
13862 };
13863 this.toggleCommentLines = function() {
13864 var state = this.session.getState(this.getCursorPosition().row);
13865 var rows = this.$getSelectedRows();
13866 this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
13867 };
13868
13869 this.toggleBlockComment = function() {
13870 var cursor = this.getCursorPosition();
13871 var state = this.session.getState(cursor.row);
13872 var range = this.getSelectionRange();
13873 this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
13874 };
13875 this.getNumberAt = function(row, column) {
13876 var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
13877 _numberRx.lastIndex = 0;
13878
13879 var s = this.session.getLine(row);
13880 while (_numberRx.lastIndex < column) {
13881 var m = _numberRx.exec(s);
13882 if(m.index <= column && m.index+m[0].length >= column){
13883 var number = {
13884 value: m[0],
13885 start: m.index,
13886 end: m.index+m[0].length
13887 };
13888 return number;
13889 }
13890 }
13891 return null;
13892 };
13893 this.modifyNumber = function(amount) {
13894 var row = this.selection.getCursor().row;
13895 var column = this.selection.getCursor().column;
13896 var charRange = new Range(row, column-1, row, column);
13897
13898 var c = this.session.getTextRange(charRange);
13899 if (!isNaN(parseFloat(c)) && isFinite(c)) {
13900 var nr = this.getNumberAt(row, column);
13901 if (nr) {
13902 var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
13903 var decimals = nr.start + nr.value.length - fp;
13904
13905 var t = parseFloat(nr.value);
13906 t *= Math.pow(10, decimals);
13907
13908
13909 if(fp !== nr.end && column < fp){
13910 amount *= Math.pow(10, nr.end - column - 1);
13911 } else {
13912 amount *= Math.pow(10, nr.end - column);
13913 }
13914
13915 t += amount;
13916 t /= Math.pow(10, decimals);
13917 var nnr = t.toFixed(decimals);
13918 var replaceRange = new Range(row, nr.start, row, nr.end);
13919 this.session.replace(replaceRange, nnr);
13920 this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
13921
13922 }
13923 }
13924 };
13925 this.removeLines = function() {
13926 var rows = this.$getSelectedRows();
13927 this.session.removeFullLines(rows.first, rows.last);
13928 this.clearSelection();
13929 };
13930
13931 this.duplicateSelection = function() {
13932 var sel = this.selection;
13933 var doc = this.session;
13934 var range = sel.getRange();
13935 var reverse = sel.isBackwards();
13936 if (range.isEmpty()) {
13937 var row = range.start.row;
13938 doc.duplicateLines(row, row);
13939 } else {
13940 var point = reverse ? range.start : range.end;
13941 var endPoint = doc.insert(point, doc.getTextRange(range), false);
13942 range.start = point;
13943 range.end = endPoint;
13944
13945 sel.setSelectionRange(range, reverse);
13946 }
13947 };
13948 this.moveLinesDown = function() {
13949 this.$moveLines(1, false);
13950 };
13951 this.moveLinesUp = function() {
13952 this.$moveLines(-1, false);
13953 };
13954 this.moveText = function(range, toPosition, copy) {
13955 return this.session.moveText(range, toPosition, copy);
13956 };
13957 this.copyLinesUp = function() {
13958 this.$moveLines(-1, true);
13959 };
13960 this.copyLinesDown = function() {
13961 this.$moveLines(1, true);
13962 };
13963 this.$moveLines = function(dir, copy) {
13964 var rows, moved;
13965 var selection = this.selection;
13966 if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
13967 var range = selection.toOrientedRange();
13968 rows = this.$getSelectedRows(range);
13969 moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
13970 if (copy && dir == -1) moved = 0;
13971 range.moveBy(moved, 0);
13972 selection.fromOrientedRange(range);
13973 } else {
13974 var ranges = selection.rangeList.ranges;
13975 selection.rangeList.detach(this.session);
13976 this.inVirtualSelectionMode = true;
13977
13978 var diff = 0;
13979 var totalDiff = 0;
13980 var l = ranges.length;
13981 for (var i = 0; i < l; i++) {
13982 var rangeIndex = i;
13983 ranges[i].moveBy(diff, 0);
13984 rows = this.$getSelectedRows(ranges[i]);
13985 var first = rows.first;
13986 var last = rows.last;
13987 while (++i < l) {
13988 if (totalDiff) ranges[i].moveBy(totalDiff, 0);
13989 var subRows = this.$getSelectedRows(ranges[i]);
13990 if (copy && subRows.first != last)
13991 break;
13992 else if (!copy && subRows.first > last + 1)
13993 break;
13994 last = subRows.last;
13995 }
13996 i--;
13997 diff = this.session.$moveLines(first, last, copy ? 0 : dir);
13998 if (copy && dir == -1) rangeIndex = i + 1;
13999 while (rangeIndex <= i) {
14000 ranges[rangeIndex].moveBy(diff, 0);
14001 rangeIndex++;
14002 }
14003 if (!copy) diff = 0;
14004 totalDiff += diff;
14005 }
14006
14007 selection.fromOrientedRange(selection.ranges[0]);
14008 selection.rangeList.attach(this.session);
14009 this.inVirtualSelectionMode = false;
14010 }
14011 };
14012 this.$getSelectedRows = function(range) {
14013 range = (range || this.getSelectionRange()).collapseRows();
14014
14015 return {
14016 first: this.session.getRowFoldStart(range.start.row),
14017 last: this.session.getRowFoldEnd(range.end.row)
14018 };
14019 };
14020
14021 this.onCompositionStart = function(text) {
14022 this.renderer.showComposition(this.getCursorPosition());
14023 };
14024
14025 this.onCompositionUpdate = function(text) {
14026 this.renderer.setCompositionText(text);
14027 };
14028
14029 this.onCompositionEnd = function() {
14030 this.renderer.hideComposition();
14031 };
14032 this.getFirstVisibleRow = function() {
14033 return this.renderer.getFirstVisibleRow();
14034 };
14035 this.getLastVisibleRow = function() {
14036 return this.renderer.getLastVisibleRow();
14037 };
14038 this.isRowVisible = function(row) {
14039 return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
14040 };
14041 this.isRowFullyVisible = function(row) {
14042 return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
14043 };
14044 this.$getVisibleRowCount = function() {
14045 return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
14046 };
14047
14048 this.$moveByPage = function(dir, select) {
14049 var renderer = this.renderer;
14050 var config = this.renderer.layerConfig;
14051 var rows = dir * Math.floor(config.height / config.lineHeight);
14052
14053 this.$blockScrolling++;
14054 if (select === true) {
14055 this.selection.$moveSelection(function(){
14056 this.moveCursorBy(rows, 0);
14057 });
14058 } else if (select === false) {
14059 this.selection.moveCursorBy(rows, 0);
14060 this.selection.clearSelection();
14061 }
14062 this.$blockScrolling--;
14063
14064 var scrollTop = renderer.scrollTop;
14065
14066 renderer.scrollBy(0, rows * config.lineHeight);
14067 if (select != null)
14068 renderer.scrollCursorIntoView(null, 0.5);
14069
14070 renderer.animateScrolling(scrollTop);
14071 };
14072 this.selectPageDown = function() {
14073 this.$moveByPage(1, true);
14074 };
14075 this.selectPageUp = function() {
14076 this.$moveByPage(-1, true);
14077 };
14078 this.gotoPageDown = function() {
14079 this.$moveByPage(1, false);
14080 };
14081 this.gotoPageUp = function() {
14082 this.$moveByPage(-1, false);
14083 };
14084 this.scrollPageDown = function() {
14085 this.$moveByPage(1);
14086 };
14087 this.scrollPageUp = function() {
14088 this.$moveByPage(-1);
14089 };
14090 this.scrollToRow = function(row) {
14091 this.renderer.scrollToRow(row);
14092 };
14093 this.scrollToLine = function(line, center, animate, callback) {
14094 this.renderer.scrollToLine(line, center, animate, callback);
14095 };
14096 this.centerSelection = function() {
14097 var range = this.getSelectionRange();
14098 var pos = {
14099 row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
14100 column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
14101 };
14102 this.renderer.alignCursor(pos, 0.5);
14103 };
14104 this.getCursorPosition = function() {
14105 return this.selection.getCursor();
14106 };
14107 this.getCursorPositionScreen = function() {
14108 return this.session.documentToScreenPosition(this.getCursorPosition());
14109 };
14110 this.getSelectionRange = function() {
14111 return this.selection.getRange();
14112 };
14113 this.selectAll = function() {
14114 this.$blockScrolling += 1;
14115 this.selection.selectAll();
14116 this.$blockScrolling -= 1;
14117 };
14118 this.clearSelection = function() {
14119 this.selection.clearSelection();
14120 };
14121 this.moveCursorTo = function(row, column) {
14122 this.selection.moveCursorTo(row, column);
14123 };
14124 this.moveCursorToPosition = function(pos) {
14125 this.selection.moveCursorToPosition(pos);
14126 };
14127 this.jumpToMatching = function(select, expand) {
14128 var cursor = this.getCursorPosition();
14129 var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
14130 var prevToken = iterator.getCurrentToken();
14131 var token = prevToken || iterator.stepForward();
14132
14133 if (!token) return;
14134 var matchType;
14135 var found = false;
14136 var depth = {};
14137 var i = cursor.column - token.start;
14138 var bracketType;
14139 var brackets = {
14140 ")": "(",
14141 "(": "(",
14142 "]": "[",
14143 "[": "[",
14144 "{": "{",
14145 "}": "{"
14146 };
14147
14148 do {
14149 if (token.value.match(/[{}()\[\]]/g)) {
14150 for (; i < token.value.length && !found; i++) {
14151 if (!brackets[token.value[i]]) {
14152 continue;
14153 }
14154
14155 bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
14156
14157 if (isNaN(depth[bracketType])) {
14158 depth[bracketType] = 0;
14159 }
14160
14161 switch (token.value[i]) {
14162 case '(':
14163 case '[':
14164 case '{':
14165 depth[bracketType]++;
14166 break;
14167 case ')':
14168 case ']':
14169 case '}':
14170 depth[bracketType]--;
14171
14172 if (depth[bracketType] === -1) {
14173 matchType = 'bracket';
14174 found = true;
14175 }
14176 break;
14177 }
14178 }
14179 }
14180 else if (token && token.type.indexOf('tag-name') !== -1) {
14181 if (isNaN(depth[token.value])) {
14182 depth[token.value] = 0;
14183 }
14184
14185 if (prevToken.value === '<') {
14186 depth[token.value]++;
14187 }
14188 else if (prevToken.value === '</') {
14189 depth[token.value]--;
14190 }
14191
14192 if (depth[token.value] === -1) {
14193 matchType = 'tag';
14194 found = true;
14195 }
14196 }
14197
14198 if (!found) {
14199 prevToken = token;
14200 token = iterator.stepForward();
14201 i = 0;
14202 }
14203 } while (token && !found);
14204 if (!matchType)
14205 return;
14206
14207 var range, pos;
14208 if (matchType === 'bracket') {
14209 range = this.session.getBracketRange(cursor);
14210 if (!range) {
14211 range = new Range(
14212 iterator.getCurrentTokenRow(),
14213 iterator.getCurrentTokenColumn() + i - 1,
14214 iterator.getCurrentTokenRow(),
14215 iterator.getCurrentTokenColumn() + i - 1
14216 );
14217 pos = range.start;
14218 if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)
14219 range = this.session.getBracketRange(pos);
14220 }
14221 }
14222 else if (matchType === 'tag') {
14223 if (token && token.type.indexOf('tag-name') !== -1)
14224 var tag = token.value;
14225 else
14226 return;
14227
14228 range = new Range(
14229 iterator.getCurrentTokenRow(),
14230 iterator.getCurrentTokenColumn() - 2,
14231 iterator.getCurrentTokenRow(),
14232 iterator.getCurrentTokenColumn() - 2
14233 );
14234 if (range.compare(cursor.row, cursor.column) === 0) {
14235 found = false;
14236 do {
14237 token = prevToken;
14238 prevToken = iterator.stepBackward();
14239
14240 if (prevToken) {
14241 if (prevToken.type.indexOf('tag-close') !== -1) {
14242 range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);
14243 }
14244
14245 if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
14246 if (prevToken.value === '<') {
14247 depth[tag]++;
14248 }
14249 else if (prevToken.value === '</') {
14250 depth[tag]--;
14251 }
14252
14253 if (depth[tag] === 0)
14254 found = true;
14255 }
14256 }
14257 } while (prevToken && !found);
14258 }
14259 if (token && token.type.indexOf('tag-name')) {
14260 pos = range.start;
14261 if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
14262 pos = range.end;
14263 }
14264 }
14265
14266 pos = range && range.cursor || pos;
14267 if (pos) {
14268 if (select) {
14269 if (range && expand) {
14270 this.selection.setRange(range);
14271 } else if (range && range.isEqual(this.getSelectionRange())) {
14272 this.clearSelection();
14273 } else {
14274 this.selection.selectTo(pos.row, pos.column);
14275 }
14276 } else {
14277 this.selection.moveTo(pos.row, pos.column);
14278 }
14279 }
14280 };
14281 this.gotoLine = function(lineNumber, column, animate) {
14282 this.selection.clearSelection();
14283 this.session.unfold({row: lineNumber - 1, column: column || 0});
14284
14285 this.$blockScrolling += 1;
14286 this.exitMultiSelectMode && this.exitMultiSelectMode();
14287 this.moveCursorTo(lineNumber - 1, column || 0);
14288 this.$blockScrolling -= 1;
14289
14290 if (!this.isRowFullyVisible(lineNumber - 1))
14291 this.scrollToLine(lineNumber - 1, true, animate);
14292 };
14293 this.navigateTo = function(row, column) {
14294 this.selection.moveTo(row, column);
14295 };
14296 this.navigateUp = function(times) {
14297 if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
14298 var selectionStart = this.selection.anchor.getPosition();
14299 return this.moveCursorToPosition(selectionStart);
14300 }
14301 this.selection.clearSelection();
14302 this.selection.moveCursorBy(-times || -1, 0);
14303 };
14304 this.navigateDown = function(times) {
14305 if (this.selection.isMultiLine() && this.selection.isBackwards()) {
14306 var selectionEnd = this.selection.anchor.getPosition();
14307 return this.moveCursorToPosition(selectionEnd);
14308 }
14309 this.selection.clearSelection();
14310 this.selection.moveCursorBy(times || 1, 0);
14311 };
14312 this.navigateLeft = function(times) {
14313 if (!this.selection.isEmpty()) {
14314 var selectionStart = this.getSelectionRange().start;
14315 this.moveCursorToPosition(selectionStart);
14316 }
14317 else {
14318 times = times || 1;
14319 while (times--) {
14320 this.selection.moveCursorLeft();
14321 }
14322 }
14323 this.clearSelection();
14324 };
14325 this.navigateRight = function(times) {
14326 if (!this.selection.isEmpty()) {
14327 var selectionEnd = this.getSelectionRange().end;
14328 this.moveCursorToPosition(selectionEnd);
14329 }
14330 else {
14331 times = times || 1;
14332 while (times--) {
14333 this.selection.moveCursorRight();
14334 }
14335 }
14336 this.clearSelection();
14337 };
14338 this.navigateLineStart = function() {
14339 this.selection.moveCursorLineStart();
14340 this.clearSelection();
14341 };
14342 this.navigateLineEnd = function() {
14343 this.selection.moveCursorLineEnd();
14344 this.clearSelection();
14345 };
14346 this.navigateFileEnd = function() {
14347 this.selection.moveCursorFileEnd();
14348 this.clearSelection();
14349 };
14350 this.navigateFileStart = function() {
14351 this.selection.moveCursorFileStart();
14352 this.clearSelection();
14353 };
14354 this.navigateWordRight = function() {
14355 this.selection.moveCursorWordRight();
14356 this.clearSelection();
14357 };
14358 this.navigateWordLeft = function() {
14359 this.selection.moveCursorWordLeft();
14360 this.clearSelection();
14361 };
14362 this.replace = function(replacement, options) {
14363 if (options)
14364 this.$search.set(options);
14365
14366 var range = this.$search.find(this.session);
14367 var replaced = 0;
14368 if (!range)
14369 return replaced;
14370
14371 if (this.$tryReplace(range, replacement)) {
14372 replaced = 1;
14373 }
14374 if (range !== null) {
14375 this.selection.setSelectionRange(range);
14376 this.renderer.scrollSelectionIntoView(range.start, range.end);
14377 }
14378
14379 return replaced;
14380 };
14381 this.replaceAll = function(replacement, options) {
14382 if (options) {
14383 this.$search.set(options);
14384 }
14385
14386 var ranges = this.$search.findAll(this.session);
14387 var replaced = 0;
14388 if (!ranges.length)
14389 return replaced;
14390
14391 this.$blockScrolling += 1;
14392
14393 var selection = this.getSelectionRange();
14394 this.selection.moveTo(0, 0);
14395
14396 for (var i = ranges.length - 1; i >= 0; --i) {
14397 if(this.$tryReplace(ranges[i], replacement)) {
14398 replaced++;
14399 }
14400 }
14401
14402 this.selection.setSelectionRange(selection);
14403 this.$blockScrolling -= 1;
14404
14405 return replaced;
14406 };
14407
14408 this.$tryReplace = function(range, replacement) {
14409 var input = this.session.getTextRange(range);
14410 replacement = this.$search.replace(input, replacement);
14411 if (replacement !== null) {
14412 range.end = this.session.replace(range, replacement);
14413 return range;
14414 } else {
14415 return null;
14416 }
14417 };
14418 this.getLastSearchOptions = function() {
14419 return this.$search.getOptions();
14420 };
14421 this.find = function(needle, options, animate) {
14422 if (!options)
14423 options = {};
14424
14425 if (typeof needle == "string" || needle instanceof RegExp)
14426 options.needle = needle;
14427 else if (typeof needle == "object")
14428 oop.mixin(options, needle);
14429
14430 var range = this.selection.getRange();
14431 if (options.needle == null) {
14432 needle = this.session.getTextRange(range)
14433 || this.$search.$options.needle;
14434 if (!needle) {
14435 range = this.session.getWordRange(range.start.row, range.start.column);
14436 needle = this.session.getTextRange(range);
14437 }
14438 this.$search.set({needle: needle});
14439 }
14440
14441 this.$search.set(options);
14442 if (!options.start)
14443 this.$search.set({start: range});
14444
14445 var newRange = this.$search.find(this.session);
14446 if (options.preventScroll)
14447 return newRange;
14448 if (newRange) {
14449 this.revealRange(newRange, animate);
14450 return newRange;
14451 }
14452 if (options.backwards)
14453 range.start = range.end;
14454 else
14455 range.end = range.start;
14456 this.selection.setRange(range);
14457 };
14458 this.findNext = function(options, animate) {
14459 this.find({skipCurrent: true, backwards: false}, options, animate);
14460 };
14461 this.findPrevious = function(options, animate) {
14462 this.find(options, {skipCurrent: true, backwards: true}, animate);
14463 };
14464
14465 this.revealRange = function(range, animate) {
14466 this.$blockScrolling += 1;
14467 this.session.unfold(range);
14468 this.selection.setSelectionRange(range);
14469 this.$blockScrolling -= 1;
14470
14471 var scrollTop = this.renderer.scrollTop;
14472 this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
14473 if (animate !== false)
14474 this.renderer.animateScrolling(scrollTop);
14475 };
14476 this.undo = function() {
14477 this.$blockScrolling++;
14478 this.session.getUndoManager().undo();
14479 this.$blockScrolling--;
14480 this.renderer.scrollCursorIntoView(null, 0.5);
14481 };
14482 this.redo = function() {
14483 this.$blockScrolling++;
14484 this.session.getUndoManager().redo();
14485 this.$blockScrolling--;
14486 this.renderer.scrollCursorIntoView(null, 0.5);
14487 };
14488 this.destroy = function() {
14489 this.renderer.destroy();
14490 this._signal("destroy", this);
14491 if (this.session) {
14492 this.session.destroy();
14493 }
14494 };
14495 this.setAutoScrollEditorIntoView = function(enable) {
14496 if (!enable)
14497 return;
14498 var rect;
14499 var self = this;
14500 var shouldScroll = false;
14501 if (!this.$scrollAnchor)
14502 this.$scrollAnchor = document.createElement("div");
14503 var scrollAnchor = this.$scrollAnchor;
14504 scrollAnchor.style.cssText = "position:absolute";
14505 this.container.insertBefore(scrollAnchor, this.container.firstChild);
14506 var onChangeSelection = this.on("changeSelection", function() {
14507 shouldScroll = true;
14508 });
14509 var onBeforeRender = this.renderer.on("beforeRender", function() {
14510 if (shouldScroll)
14511 rect = self.renderer.container.getBoundingClientRect();
14512 });
14513 var onAfterRender = this.renderer.on("afterRender", function() {
14514 if (shouldScroll && rect && (self.isFocused()
14515 || self.searchBox && self.searchBox.isFocused())
14516 ) {
14517 var renderer = self.renderer;
14518 var pos = renderer.$cursorLayer.$pixelPos;
14519 var config = renderer.layerConfig;
14520 var top = pos.top - config.offset;
14521 if (pos.top >= 0 && top + rect.top < 0) {
14522 shouldScroll = true;
14523 } else if (pos.top < config.height &&
14524 pos.top + rect.top + config.lineHeight > window.innerHeight) {
14525 shouldScroll = false;
14526 } else {
14527 shouldScroll = null;
14528 }
14529 if (shouldScroll != null) {
14530 scrollAnchor.style.top = top + "px";
14531 scrollAnchor.style.left = pos.left + "px";
14532 scrollAnchor.style.height = config.lineHeight + "px";
14533 scrollAnchor.scrollIntoView(shouldScroll);
14534 }
14535 shouldScroll = rect = null;
14536 }
14537 });
14538 this.setAutoScrollEditorIntoView = function(enable) {
14539 if (enable)
14540 return;
14541 delete this.setAutoScrollEditorIntoView;
14542 this.off("changeSelection", onChangeSelection);
14543 this.renderer.off("afterRender", onAfterRender);
14544 this.renderer.off("beforeRender", onBeforeRender);
14545 };
14546 };
14547
14548
14549 this.$resetCursorStyle = function() {
14550 var style = this.$cursorStyle || "ace";
14551 var cursorLayer = this.renderer.$cursorLayer;
14552 if (!cursorLayer)
14553 return;
14554 cursorLayer.setSmoothBlinking(/smooth/.test(style));
14555 cursorLayer.isBlinking = !this.$readOnly && style != "wide";
14556 dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
14557 };
14558
14559 }).call(Editor.prototype);
14560
14561
14562
14563 config.defineOptions(Editor.prototype, "editor", {
14564 selectionStyle: {
14565 set: function(style) {
14566 this.onSelectionChange();
14567 this._signal("changeSelectionStyle", {data: style});
14568 },
14569 initialValue: "line"
14570 },
14571 highlightActiveLine: {
14572 set: function() {this.$updateHighlightActiveLine();},
14573 initialValue: true
14574 },
14575 highlightSelectedWord: {
14576 set: function(shouldHighlight) {this.$onSelectionChange();},
14577 initialValue: true
14578 },
14579 readOnly: {
14580 set: function(readOnly) {
14581 this.$resetCursorStyle();
14582 },
14583 initialValue: false
14584 },
14585 cursorStyle: {
14586 set: function(val) { this.$resetCursorStyle(); },
14587 values: ["ace", "slim", "smooth", "wide"],
14588 initialValue: "ace"
14589 },
14590 mergeUndoDeltas: {
14591 values: [false, true, "always"],
14592 initialValue: true
14593 },
14594 behavioursEnabled: {initialValue: true},
14595 wrapBehavioursEnabled: {initialValue: true},
14596 autoScrollEditorIntoView: {
14597 set: function(val) {this.setAutoScrollEditorIntoView(val);}
14598 },
14599 keyboardHandler: {
14600 set: function(val) { this.setKeyboardHandler(val); },
14601 get: function() { return this.keybindingId; },
14602 handlesSet: true
14603 },
14604
14605 hScrollBarAlwaysVisible: "renderer",
14606 vScrollBarAlwaysVisible: "renderer",
14607 highlightGutterLine: "renderer",
14608 animatedScroll: "renderer",
14609 showInvisibles: "renderer",
14610 showPrintMargin: "renderer",
14611 printMarginColumn: "renderer",
14612 printMargin: "renderer",
14613 fadeFoldWidgets: "renderer",
14614 showFoldWidgets: "renderer",
14615 showLineNumbers: "renderer",
14616 showGutter: "renderer",
14617 displayIndentGuides: "renderer",
14618 fontSize: "renderer",
14619 fontFamily: "renderer",
14620 maxLines: "renderer",
14621 minLines: "renderer",
14622 scrollPastEnd: "renderer",
14623 fixedWidthGutter: "renderer",
14624 theme: "renderer",
14625
14626 scrollSpeed: "$mouseHandler",
14627 dragDelay: "$mouseHandler",
14628 dragEnabled: "$mouseHandler",
14629 focusTimout: "$mouseHandler",
14630 tooltipFollowsMouse: "$mouseHandler",
14631
14632 firstLineNumber: "session",
14633 overwrite: "session",
14634 newLineMode: "session",
14635 useWorker: "session",
14636 useSoftTabs: "session",
14637 tabSize: "session",
14638 wrap: "session",
14639 indentedSoftWrap: "session",
14640 foldStyle: "session",
14641 mode: "session"
14642 });
14643
14644 exports.Editor = Editor;
14645 });
14646
14647 define("ace/undomanager",["require","exports","module"], function(require, exports, module) {
14648 "use strict";
14649 var UndoManager = function() {
14650 this.reset();
14651 };
14652
14653 (function() {
14654 this.execute = function(options) {
14655 var deltaSets = options.args[0];
14656 this.$doc = options.args[1];
14657 if (options.merge && this.hasUndo()){
14658 this.dirtyCounter--;
14659 deltaSets = this.$undoStack.pop().concat(deltaSets);
14660 }
14661 this.$undoStack.push(deltaSets);
14662 this.$redoStack = [];
14663 if (this.dirtyCounter < 0) {
14664 this.dirtyCounter = NaN;
14665 }
14666 this.dirtyCounter++;
14667 };
14668 this.undo = function(dontSelect) {
14669 var deltaSets = this.$undoStack.pop();
14670 var undoSelectionRange = null;
14671 if (deltaSets) {
14672 undoSelectionRange = this.$doc.undoChanges(deltaSets, dontSelect);
14673 this.$redoStack.push(deltaSets);
14674 this.dirtyCounter--;
14675 }
14676
14677 return undoSelectionRange;
14678 };
14679 this.redo = function(dontSelect) {
14680 var deltaSets = this.$redoStack.pop();
14681 var redoSelectionRange = null;
14682 if (deltaSets) {
14683 redoSelectionRange =
14684 this.$doc.redoChanges(this.$deserializeDeltas(deltaSets), dontSelect);
14685 this.$undoStack.push(deltaSets);
14686 this.dirtyCounter++;
14687 }
14688 return redoSelectionRange;
14689 };
14690 this.reset = function() {
14691 this.$undoStack = [];
14692 this.$redoStack = [];
14693 this.dirtyCounter = 0;
14694 };
14695 this.hasUndo = function() {
14696 return this.$undoStack.length > 0;
14697 };
14698 this.hasRedo = function() {
14699 return this.$redoStack.length > 0;
14700 };
14701 this.markClean = function() {
14702 this.dirtyCounter = 0;
14703 };
14704 this.isClean = function() {
14705 return this.dirtyCounter === 0;
14706 };
14707 this.$serializeDeltas = function(deltaSets) {
14708 return cloneDeltaSetsObj(deltaSets, $serializeDelta);
14709 };
14710 this.$deserializeDeltas = function(deltaSets) {
14711 return cloneDeltaSetsObj(deltaSets, $deserializeDelta);
14712 };
14713
14714 function $serializeDelta(delta){
14715 return {
14716 action: delta.action,
14717 start: delta.start,
14718 end: delta.end,
14719 lines: delta.lines.length == 1 ? null : delta.lines,
14720 text: delta.lines.length == 1 ? delta.lines[0] : null
14721 };
14722 }
14723
14724 function $deserializeDelta(delta) {
14725 return {
14726 action: delta.action,
14727 start: delta.start,
14728 end: delta.end,
14729 lines: delta.lines || [delta.text]
14730 };
14731 }
14732
14733 function cloneDeltaSetsObj(deltaSets_old, fnGetModifiedDelta) {
14734 var deltaSets_new = new Array(deltaSets_old.length);
14735 for (var i = 0; i < deltaSets_old.length; i++) {
14736 var deltaSet_old = deltaSets_old[i];
14737 var deltaSet_new = { group: deltaSet_old.group, deltas: new Array(deltaSet_old.length)};
14738
14739 for (var j = 0; j < deltaSet_old.deltas.length; j++) {
14740 var delta_old = deltaSet_old.deltas[j];
14741 deltaSet_new.deltas[j] = fnGetModifiedDelta(delta_old);
14742 }
14743
14744 deltaSets_new[i] = deltaSet_new;
14745 }
14746 return deltaSets_new;
14747 }
14748
14749 }).call(UndoManager.prototype);
14750
14751 exports.UndoManager = UndoManager;
14752 });
14753
14754 define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"], function(require, exports, module) {
14755 "use strict";
14756
14757 var dom = require("../lib/dom");
14758 var oop = require("../lib/oop");
14759 var lang = require("../lib/lang");
14760 var EventEmitter = require("../lib/event_emitter").EventEmitter;
14761
14762 var Gutter = function(parentEl) {
14763 this.element = dom.createElement("div");
14764 this.element.className = "ace_layer ace_gutter-layer";
14765 parentEl.appendChild(this.element);
14766 this.setShowFoldWidgets(this.$showFoldWidgets);
14767
14768 this.gutterWidth = 0;
14769
14770 this.$annotations = [];
14771 this.$updateAnnotations = this.$updateAnnotations.bind(this);
14772
14773 this.$cells = [];
14774 };
14775
14776 (function() {
14777
14778 oop.implement(this, EventEmitter);
14779
14780 this.setSession = function(session) {
14781 if (this.session)
14782 this.session.removeEventListener("change", this.$updateAnnotations);
14783 this.session = session;
14784 if (session)
14785 session.on("change", this.$updateAnnotations);
14786 };
14787
14788 this.addGutterDecoration = function(row, className){
14789 if (window.console)
14790 console.warn && console.warn("deprecated use session.addGutterDecoration");
14791 this.session.addGutterDecoration(row, className);
14792 };
14793
14794 this.removeGutterDecoration = function(row, className){
14795 if (window.console)
14796 console.warn && console.warn("deprecated use session.removeGutterDecoration");
14797 this.session.removeGutterDecoration(row, className);
14798 };
14799
14800 this.setAnnotations = function(annotations) {
14801 this.$annotations = [];
14802 for (var i = 0; i < annotations.length; i++) {
14803 var annotation = annotations[i];
14804 var row = annotation.row;
14805 var rowInfo = this.$annotations[row];
14806 if (!rowInfo)
14807 rowInfo = this.$annotations[row] = {text: []};
14808
14809 var annoText = annotation.text;
14810 annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || "";
14811
14812 if (rowInfo.text.indexOf(annoText) === -1)
14813 rowInfo.text.push(annoText);
14814
14815 var type = annotation.type;
14816 if (type == "error")
14817 rowInfo.className = " ace_error";
14818 else if (type == "warning" && rowInfo.className != " ace_error")
14819 rowInfo.className = " ace_warning";
14820 else if (type == "info" && (!rowInfo.className))
14821 rowInfo.className = " ace_info";
14822 }
14823 };
14824
14825 this.$updateAnnotations = function (delta) {
14826 if (!this.$annotations.length)
14827 return;
14828 var firstRow = delta.start.row;
14829 var len = delta.end.row - firstRow;
14830 if (len === 0) {
14831 } else if (delta.action == 'remove') {
14832 this.$annotations.splice(firstRow, len + 1, null);
14833 } else {
14834 var args = new Array(len + 1);
14835 args.unshift(firstRow, 1);
14836 this.$annotations.splice.apply(this.$annotations, args);
14837 }
14838 };
14839
14840 this.update = function(config) {
14841 var session = this.session;
14842 var firstRow = config.firstRow;
14843 var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar
14844 session.getLength() - 1);
14845 var fold = session.getNextFoldLine(firstRow);
14846 var foldStart = fold ? fold.start.row : Infinity;
14847 var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
14848 var breakpoints = session.$breakpoints;
14849 var decorations = session.$decorations;
14850 var firstLineNumber = session.$firstLineNumber;
14851 var lastLineNumber = 0;
14852
14853 var gutterRenderer = session.gutterRenderer || this.$renderer;
14854
14855 var cell = null;
14856 var index = -1;
14857 var row = firstRow;
14858 while (true) {
14859 if (row > foldStart) {
14860 row = fold.end.row + 1;
14861 fold = session.getNextFoldLine(row, fold);
14862 foldStart = fold ? fold.start.row : Infinity;
14863 }
14864 if (row > lastRow) {
14865 while (this.$cells.length > index + 1) {
14866 cell = this.$cells.pop();
14867 this.element.removeChild(cell.element);
14868 }
14869 break;
14870 }
14871
14872 cell = this.$cells[++index];
14873 if (!cell) {
14874 cell = {element: null, textNode: null, foldWidget: null};
14875 cell.element = dom.createElement("div");
14876 cell.textNode = document.createTextNode('');
14877 cell.element.appendChild(cell.textNode);
14878 this.element.appendChild(cell.element);
14879 this.$cells[index] = cell;
14880 }
14881
14882 var className = "ace_gutter-cell ";
14883 if (breakpoints[row])
14884 className += breakpoints[row];
14885 if (decorations[row])
14886 className += decorations[row];
14887 if (this.$annotations[row])
14888 className += this.$annotations[row].className;
14889 if (cell.element.className != className)
14890 cell.element.className = className;
14891
14892 var height = session.getRowLength(row) * config.lineHeight + "px";
14893 if (height != cell.element.style.height)
14894 cell.element.style.height = height;
14895
14896 if (foldWidgets) {
14897 var c = foldWidgets[row];
14898 if (c == null)
14899 c = foldWidgets[row] = session.getFoldWidget(row);
14900 }
14901
14902 if (c) {
14903 if (!cell.foldWidget) {
14904 cell.foldWidget = dom.createElement("span");
14905 cell.element.appendChild(cell.foldWidget);
14906 }
14907 var className = "ace_fold-widget ace_" + c;
14908 if (c == "start" && row == foldStart && row < fold.end.row)
14909 className += " ace_closed";
14910 else
14911 className += " ace_open";
14912 if (cell.foldWidget.className != className)
14913 cell.foldWidget.className = className;
14914
14915 var height = config.lineHeight + "px";
14916 if (cell.foldWidget.style.height != height)
14917 cell.foldWidget.style.height = height;
14918 } else {
14919 if (cell.foldWidget) {
14920 cell.element.removeChild(cell.foldWidget);
14921 cell.foldWidget = null;
14922 }
14923 }
14924
14925 var text = lastLineNumber = gutterRenderer
14926 ? gutterRenderer.getText(session, row)
14927 : row + firstLineNumber;
14928 if (text !== cell.textNode.data)
14929 cell.textNode.data = text;
14930
14931 row++;
14932 }
14933
14934 this.element.style.height = config.minHeight + "px";
14935
14936 if (this.$fixedWidth || session.$useWrapMode)
14937 lastLineNumber = session.getLength() + firstLineNumber;
14938
14939 var gutterWidth = gutterRenderer
14940 ? gutterRenderer.getWidth(session, lastLineNumber, config)
14941 : lastLineNumber.toString().length * config.characterWidth;
14942
14943 var padding = this.$padding || this.$computePadding();
14944 gutterWidth += padding.left + padding.right;
14945 if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {
14946 this.gutterWidth = gutterWidth;
14947 this.element.style.width = Math.ceil(this.gutterWidth) + "px";
14948 this._emit("changeGutterWidth", gutterWidth);
14949 }
14950 };
14951
14952 this.$fixedWidth = false;
14953
14954 this.$showLineNumbers = true;
14955 this.$renderer = "";
14956 this.setShowLineNumbers = function(show) {
14957 this.$renderer = !show && {
14958 getWidth: function() {return "";},
14959 getText: function() {return "";}
14960 };
14961 };
14962
14963 this.getShowLineNumbers = function() {
14964 return this.$showLineNumbers;
14965 };
14966
14967 this.$showFoldWidgets = true;
14968 this.setShowFoldWidgets = function(show) {
14969 if (show)
14970 dom.addCssClass(this.element, "ace_folding-enabled");
14971 else
14972 dom.removeCssClass(this.element, "ace_folding-enabled");
14973
14974 this.$showFoldWidgets = show;
14975 this.$padding = null;
14976 };
14977
14978 this.getShowFoldWidgets = function() {
14979 return this.$showFoldWidgets;
14980 };
14981
14982 this.$computePadding = function() {
14983 if (!this.element.firstChild)
14984 return {left: 0, right: 0};
14985 var style = dom.computedStyle(this.element.firstChild);
14986 this.$padding = {};
14987 this.$padding.left = parseInt(style.paddingLeft) + 1 || 0;
14988 this.$padding.right = parseInt(style.paddingRight) || 0;
14989 return this.$padding;
14990 };
14991
14992 this.getRegion = function(point) {
14993 var padding = this.$padding || this.$computePadding();
14994 var rect = this.element.getBoundingClientRect();
14995 if (point.x < padding.left + rect.left)
14996 return "markers";
14997 if (this.$showFoldWidgets && point.x > rect.right - padding.right)
14998 return "foldWidgets";
14999 };
15000
15001 }).call(Gutter.prototype);
15002
15003 exports.Gutter = Gutter;
15004
15005 });
15006
15007 define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"], function(require, exports, module) {
15008 "use strict";
15009
15010 var Range = require("../range").Range;
15011 var dom = require("../lib/dom");
15012
15013 var Marker = function(parentEl) {
15014 this.element = dom.createElement("div");
15015 this.element.className = "ace_layer ace_marker-layer";
15016 parentEl.appendChild(this.element);
15017 };
15018
15019 (function() {
15020
15021 this.$padding = 0;
15022
15023 this.setPadding = function(padding) {
15024 this.$padding = padding;
15025 };
15026 this.setSession = function(session) {
15027 this.session = session;
15028 };
15029
15030 this.setMarkers = function(markers) {
15031 this.markers = markers;
15032 };
15033
15034 this.update = function(config) {
15035 if (!config) return;
15036
15037 this.config = config;
15038
15039
15040 var html = [];
15041 for (var key in this.markers) {
15042 var marker = this.markers[key];
15043
15044 if (!marker.range) {
15045 marker.update(html, this, this.session, config);
15046 continue;
15047 }
15048
15049 var range = marker.range.clipRows(config.firstRow, config.lastRow);
15050 if (range.isEmpty()) continue;
15051
15052 range = range.toScreenRange(this.session);
15053 if (marker.renderer) {
15054 var top = this.$getTop(range.start.row, config);
15055 var left = this.$padding + (this.session.$bidiHandler.isBidiRow(range.start.row)
15056 ? this.session.$bidiHandler.getPosLeft(range.start.column)
15057 : range.start.column * config.characterWidth);
15058 marker.renderer(html, range, left, top, config);
15059 } else if (marker.type == "fullLine") {
15060 this.drawFullLineMarker(html, range, marker.clazz, config);
15061 } else if (marker.type == "screenLine") {
15062 this.drawScreenLineMarker(html, range, marker.clazz, config);
15063 } else if (range.isMultiLine()) {
15064 if (marker.type == "text")
15065 this.drawTextMarker(html, range, marker.clazz, config);
15066 else
15067 this.drawMultiLineMarker(html, range, marker.clazz, config);
15068 } else {
15069 if (this.session.$bidiHandler.isBidiRow(range.start.row)) {
15070 this.drawBidiSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config);
15071 } else {
15072 this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config);
15073 }
15074 }
15075 }
15076 this.element.innerHTML = html.join("");
15077 };
15078
15079 this.$getTop = function(row, layerConfig) {
15080 return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
15081 };
15082
15083 function getBorderClass(tl, tr, br, bl) {
15084 return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0);
15085 }
15086 this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) {
15087 var session = this.session;
15088 var start = range.start.row;
15089 var end = range.end.row;
15090 var row = start;
15091 var prev = 0;
15092 var curr = 0;
15093 var next = session.getScreenLastRowColumn(row);
15094 var clazzModified = null;
15095 var lineRange = new Range(row, range.start.column, row, curr);
15096 for (; row <= end; row++) {
15097 lineRange.start.row = lineRange.end.row = row;
15098 lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row);
15099 lineRange.end.column = next;
15100 prev = curr;
15101 curr = next;
15102 next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column;
15103 clazzModified = clazz + (row == start ? " ace_start" : "") + " ace_br"
15104 + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end);
15105
15106 if (this.session.$bidiHandler.isBidiRow(row)) {
15107 this.drawBidiSingleLineMarker(stringBuilder, lineRange, clazzModified,
15108 layerConfig, row == end ? 0 : 1, extraStyle);
15109 } else {
15110 this.drawSingleLineMarker(stringBuilder, lineRange, clazzModified,
15111 layerConfig, row == end ? 0 : 1, extraStyle);
15112 }
15113 }
15114 };
15115 this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15116 var padding = this.$padding;
15117 var height, top, left;
15118 extraStyle = extraStyle || "";
15119 if (this.session.$bidiHandler.isBidiRow(range.start.row)) {
15120 var range1 = range.clone();
15121 range1.end.row = range1.start.row;
15122 range1.end.column = this.session.getLine(range1.start.row).length;
15123 this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br1 ace_start", config, null, extraStyle);
15124 } else {
15125 height = config.lineHeight;
15126 top = this.$getTop(range.start.row, config);
15127 left = padding + range.start.column * config.characterWidth;
15128 stringBuilder.push(
15129 "<div class='", clazz, " ace_br1 ace_start' style='",
15130 "height:", height, "px;",
15131 "right:0;",
15132 "top:", top, "px;",
15133 "left:", left, "px;", extraStyle, "'></div>"
15134 );
15135 }
15136 if (this.session.$bidiHandler.isBidiRow(range.end.row)) {
15137 var range1 = range.clone();
15138 range1.start.row = range1.end.row;
15139 range1.start.column = 0;
15140 this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br12", config, null, extraStyle);
15141 } else {
15142 var width = range.end.column * config.characterWidth;
15143 height = config.lineHeight;
15144 top = this.$getTop(range.end.row, config);
15145 stringBuilder.push(
15146 "<div class='", clazz, " ace_br12' style='",
15147 "height:", height, "px;",
15148 "width:", width, "px;",
15149 "top:", top, "px;",
15150 "left:", padding, "px;", extraStyle, "'></div>"
15151 );
15152 }
15153 height = (range.end.row - range.start.row - 1) * config.lineHeight;
15154 if (height <= 0)
15155 return;
15156 top = this.$getTop(range.start.row + 1, config);
15157
15158 var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8);
15159
15160 stringBuilder.push(
15161 "<div class='", clazz, (radiusClass ? " ace_br" + radiusClass : ""), "' style='",
15162 "height:", height, "px;",
15163 "right:0;",
15164 "top:", top, "px;",
15165 "left:", padding, "px;", extraStyle, "'></div>"
15166 );
15167 };
15168 this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
15169 var height = config.lineHeight;
15170 var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;
15171
15172 var top = this.$getTop(range.start.row, config);
15173 var left = this.$padding + range.start.column * config.characterWidth;
15174
15175 stringBuilder.push(
15176 "<div class='", clazz, "' style='",
15177 "height:", height, "px;",
15178 "width:", width, "px;",
15179 "top:", top, "px;",
15180 "left:", left, "px;", extraStyle || "", "'></div>"
15181 );
15182 };
15183 this.drawBidiSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
15184 var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding;
15185 var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column);
15186
15187 selections.forEach(function(selection) {
15188 stringBuilder.push(
15189 "<div class='", clazz, "' style='",
15190 "height:", height, "px;",
15191 "width:", selection.width + (extraLength || 0), "px;",
15192 "top:", top, "px;",
15193 "left:", padding + selection.left, "px;", extraStyle || "", "'></div>"
15194 );
15195 });
15196 };
15197
15198 this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15199 var top = this.$getTop(range.start.row, config);
15200 var height = config.lineHeight;
15201 if (range.start.row != range.end.row)
15202 height += this.$getTop(range.end.row, config) - top;
15203
15204 stringBuilder.push(
15205 "<div class='", clazz, "' style='",
15206 "height:", height, "px;",
15207 "top:", top, "px;",
15208 "left:0;right:0;", extraStyle || "", "'></div>"
15209 );
15210 };
15211
15212 this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
15213 var top = this.$getTop(range.start.row, config);
15214 var height = config.lineHeight;
15215
15216 stringBuilder.push(
15217 "<div class='", clazz, "' style='",
15218 "height:", height, "px;",
15219 "top:", top, "px;",
15220 "left:0;right:0;", extraStyle || "", "'></div>"
15221 );
15222 };
15223
15224 }).call(Marker.prototype);
15225
15226 exports.Marker = Marker;
15227
15228 });
15229
15230 define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(require, exports, module) {
15231 "use strict";
15232
15233 var oop = require("../lib/oop");
15234 var dom = require("../lib/dom");
15235 var lang = require("../lib/lang");
15236 var useragent = require("../lib/useragent");
15237 var EventEmitter = require("../lib/event_emitter").EventEmitter;
15238
15239 var Text = function(parentEl) {
15240 this.element = dom.createElement("div");
15241 this.element.className = "ace_layer ace_text-layer";
15242 parentEl.appendChild(this.element);
15243 this.$updateEolChar = this.$updateEolChar.bind(this);
15244 };
15245
15246 (function() {
15247
15248 oop.implement(this, EventEmitter);
15249
15250 this.EOF_CHAR = "\xB6";
15251 this.EOL_CHAR_LF = "\xAC";
15252 this.EOL_CHAR_CRLF = "\xa4";
15253 this.EOL_CHAR = this.EOL_CHAR_LF;
15254 this.TAB_CHAR = "\u2014"; //"\u21E5";
15255 this.SPACE_CHAR = "\xB7";
15256 this.$padding = 0;
15257
15258 this.$updateEolChar = function() {
15259 var EOL_CHAR = this.session.doc.getNewLineCharacter() == "\n"
15260 ? this.EOL_CHAR_LF
15261 : this.EOL_CHAR_CRLF;
15262 if (this.EOL_CHAR != EOL_CHAR) {
15263 this.EOL_CHAR = EOL_CHAR;
15264 return true;
15265 }
15266 };
15267
15268 this.setPadding = function(padding) {
15269 this.$padding = padding;
15270 this.element.style.padding = "0 " + padding + "px";
15271 };
15272
15273 this.getLineHeight = function() {
15274 return this.$fontMetrics.$characterSize.height || 0;
15275 };
15276
15277 this.getCharacterWidth = function() {
15278 return this.$fontMetrics.$characterSize.width || 0;
15279 };
15280
15281 this.$setFontMetrics = function(measure) {
15282 this.$fontMetrics = measure;
15283 this.$fontMetrics.on("changeCharacterSize", function(e) {
15284 this._signal("changeCharacterSize", e);
15285 }.bind(this));
15286 this.$pollSizeChanges();
15287 };
15288
15289 this.checkForSizeChanges = function() {
15290 this.$fontMetrics.checkForSizeChanges();
15291 };
15292 this.$pollSizeChanges = function() {
15293 return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();
15294 };
15295 this.setSession = function(session) {
15296 this.session = session;
15297 if (session)
15298 this.$computeTabString();
15299 };
15300
15301 this.showInvisibles = false;
15302 this.setShowInvisibles = function(showInvisibles) {
15303 if (this.showInvisibles == showInvisibles)
15304 return false;
15305
15306 this.showInvisibles = showInvisibles;
15307 this.$computeTabString();
15308 return true;
15309 };
15310
15311 this.displayIndentGuides = true;
15312 this.setDisplayIndentGuides = function(display) {
15313 if (this.displayIndentGuides == display)
15314 return false;
15315
15316 this.displayIndentGuides = display;
15317 this.$computeTabString();
15318 return true;
15319 };
15320
15321 this.$tabStrings = [];
15322 this.onChangeTabSize =
15323 this.$computeTabString = function() {
15324 var tabSize = this.session.getTabSize();
15325 this.tabSize = tabSize;
15326 var tabStr = this.$tabStrings = [0];
15327 for (var i = 1; i < tabSize + 1; i++) {
15328 if (this.showInvisibles) {
15329 tabStr.push("<span class='ace_invisible ace_invisible_tab'>"
15330 + lang.stringRepeat(this.TAB_CHAR, i)
15331 + "</span>");
15332 } else {
15333 tabStr.push(lang.stringRepeat(" ", i));
15334 }
15335 }
15336 if (this.displayIndentGuides) {
15337 this.$indentGuideRe = /\s\S| \t|\t |\s$/;
15338 var className = "ace_indent-guide";
15339 var spaceClass = "";
15340 var tabClass = "";
15341 if (this.showInvisibles) {
15342 className += " ace_invisible";
15343 spaceClass = " ace_invisible_space";
15344 tabClass = " ace_invisible_tab";
15345 var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);
15346 var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize);
15347 } else{
15348 var spaceContent = lang.stringRepeat(" ", this.tabSize);
15349 var tabContent = spaceContent;
15350 }
15351
15352 this.$tabStrings[" "] = "<span class='" + className + spaceClass + "'>" + spaceContent + "</span>";
15353 this.$tabStrings["\t"] = "<span class='" + className + tabClass + "'>" + tabContent + "</span>";
15354 }
15355 };
15356
15357 this.updateLines = function(config, firstRow, lastRow) {
15358 if (this.config.lastRow != config.lastRow ||
15359 this.config.firstRow != config.firstRow) {
15360 this.scrollLines(config);
15361 }
15362 this.config = config;
15363
15364 var first = Math.max(firstRow, config.firstRow);
15365 var last = Math.min(lastRow, config.lastRow);
15366
15367 var lineElements = this.element.childNodes;
15368 var lineElementsIdx = 0;
15369
15370 for (var row = config.firstRow; row < first; row++) {
15371 var foldLine = this.session.getFoldLine(row);
15372 if (foldLine) {
15373 if (foldLine.containsRow(first)) {
15374 first = foldLine.start.row;
15375 break;
15376 } else {
15377 row = foldLine.end.row;
15378 }
15379 }
15380 lineElementsIdx ++;
15381 }
15382
15383 var row = first;
15384 var foldLine = this.session.getNextFoldLine(row);
15385 var foldStart = foldLine ? foldLine.start.row : Infinity;
15386
15387 while (true) {
15388 if (row > foldStart) {
15389 row = foldLine.end.row+1;
15390 foldLine = this.session.getNextFoldLine(row, foldLine);
15391 foldStart = foldLine ? foldLine.start.row :Infinity;
15392 }
15393 if (row > last)
15394 break;
15395
15396 var lineElement = lineElements[lineElementsIdx++];
15397 if (lineElement) {
15398 var html = [];
15399 this.$renderLine(
15400 html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
15401 );
15402 lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
15403 lineElement.innerHTML = html.join("");
15404 }
15405 row++;
15406 }
15407 };
15408
15409 this.scrollLines = function(config) {
15410 var oldConfig = this.config;
15411 this.config = config;
15412
15413 if (!oldConfig || oldConfig.lastRow < config.firstRow)
15414 return this.update(config);
15415
15416 if (config.lastRow < oldConfig.firstRow)
15417 return this.update(config);
15418
15419 var el = this.element;
15420 if (oldConfig.firstRow < config.firstRow)
15421 for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
15422 el.removeChild(el.firstChild);
15423
15424 if (oldConfig.lastRow > config.lastRow)
15425 for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
15426 el.removeChild(el.lastChild);
15427
15428 if (config.firstRow < oldConfig.firstRow) {
15429 var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
15430 if (el.firstChild)
15431 el.insertBefore(fragment, el.firstChild);
15432 else
15433 el.appendChild(fragment);
15434 }
15435
15436 if (config.lastRow > oldConfig.lastRow) {
15437 var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);
15438 el.appendChild(fragment);
15439 }
15440 };
15441
15442 this.$renderLinesFragment = function(config, firstRow, lastRow) {
15443 var fragment = this.element.ownerDocument.createDocumentFragment();
15444 var row = firstRow;
15445 var foldLine = this.session.getNextFoldLine(row);
15446 var foldStart = foldLine ? foldLine.start.row : Infinity;
15447
15448 while (true) {
15449 if (row > foldStart) {
15450 row = foldLine.end.row+1;
15451 foldLine = this.session.getNextFoldLine(row, foldLine);
15452 foldStart = foldLine ? foldLine.start.row : Infinity;
15453 }
15454 if (row > lastRow)
15455 break;
15456
15457 var container = dom.createElement("div");
15458
15459 var html = [];
15460 this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
15461 container.innerHTML = html.join("");
15462 if (this.$useLineGroups()) {
15463 container.className = 'ace_line_group';
15464 fragment.appendChild(container);
15465 container.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
15466
15467 } else {
15468 while(container.firstChild)
15469 fragment.appendChild(container.firstChild);
15470 }
15471
15472 row++;
15473 }
15474 return fragment;
15475 };
15476
15477 this.update = function(config) {
15478 this.config = config;
15479
15480 var html = [];
15481 var firstRow = config.firstRow, lastRow = config.lastRow;
15482
15483 var row = firstRow;
15484 var foldLine = this.session.getNextFoldLine(row);
15485 var foldStart = foldLine ? foldLine.start.row : Infinity;
15486
15487 while (true) {
15488 if (row > foldStart) {
15489 row = foldLine.end.row+1;
15490 foldLine = this.session.getNextFoldLine(row, foldLine);
15491 foldStart = foldLine ? foldLine.start.row :Infinity;
15492 }
15493 if (row > lastRow)
15494 break;
15495
15496 if (this.$useLineGroups())
15497 html.push("<div class='ace_line_group' style='height:", config.lineHeight*this.session.getRowLength(row), "px'>");
15498
15499 this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
15500
15501 if (this.$useLineGroups())
15502 html.push("</div>"); // end the line group
15503
15504 row++;
15505 }
15506 this.element.innerHTML = html.join("");
15507 };
15508
15509 this.$textToken = {
15510 "text": true,
15511 "rparen": true,
15512 "lparen": true
15513 };
15514
15515 this.$renderToken = function(stringBuilder, screenColumn, token, value) {
15516 var self = this;
15517 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;
15518 var replaceFunc = function(c, a, b, tabIdx, idx4) {
15519 if (a) {
15520 return self.showInvisibles
15521 ? "<span class='ace_invisible ace_invisible_space'>" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "</span>"
15522 : c;
15523 } else if (c == "&") {
15524 return "&#38;";
15525 } else if (c == "<") {
15526 return "&#60;";
15527 } else if (c == ">") {
15528 return "&#62;";
15529 } else if (c == "\t") {
15530 var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
15531 screenColumn += tabSize - 1;
15532 return self.$tabStrings[tabSize];
15533 } else if (c == "\u3000") {
15534 var classToUse = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk";
15535 var space = self.showInvisibles ? self.SPACE_CHAR : "";
15536 screenColumn += 1;
15537 return "<span class='" + classToUse + "' style='width:" +
15538 (self.config.characterWidth * 2) +
15539 "px'>" + space + "</span>";
15540 } else if (b) {
15541 return "<span class='ace_invisible ace_invisible_space ace_invalid'>" + self.SPACE_CHAR + "</span>";
15542 } else {
15543 screenColumn += 1;
15544 return "<span class='ace_cjk' style='width:" +
15545 (self.config.characterWidth * 2) +
15546 "px'>" + c + "</span>";
15547 }
15548 };
15549
15550 var output = value.replace(replaceReg, replaceFunc);
15551
15552 if (!this.$textToken[token.type]) {
15553 var classes = "ace_" + token.type.replace(/\./g, " ace_");
15554 var style = "";
15555 if (token.type == "fold")
15556 style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' ";
15557 stringBuilder.push("<span class='", classes, "'", style, ">", output, "</span>");
15558 }
15559 else {
15560 stringBuilder.push(output);
15561 }
15562 return screenColumn + value.length;
15563 };
15564
15565 this.renderIndentGuide = function(stringBuilder, value, max) {
15566 var cols = value.search(this.$indentGuideRe);
15567 if (cols <= 0 || cols >= max)
15568 return value;
15569 if (value[0] == " ") {
15570 cols -= cols % this.tabSize;
15571 stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize));
15572 return value.substr(cols);
15573 } else if (value[0] == "\t") {
15574 stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols));
15575 return value.substr(cols);
15576 }
15577 return value;
15578 };
15579
15580 this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
15581 var chars = 0;
15582 var split = 0;
15583 var splitChars = splits[0];
15584 var screenColumn = 0;
15585
15586 for (var i = 0; i < tokens.length; i++) {
15587 var token = tokens[i];
15588 var value = token.value;
15589 if (i == 0 && this.displayIndentGuides) {
15590 chars = value.length;
15591 value = this.renderIndentGuide(stringBuilder, value, splitChars);
15592 if (!value)
15593 continue;
15594 chars -= value.length;
15595 }
15596
15597 if (chars + value.length < splitChars) {
15598 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15599 chars += value.length;
15600 } else {
15601 while (chars + value.length >= splitChars) {
15602 screenColumn = this.$renderToken(
15603 stringBuilder, screenColumn,
15604 token, value.substring(0, splitChars - chars)
15605 );
15606 value = value.substring(splitChars - chars);
15607 chars = splitChars;
15608
15609 if (!onlyContents) {
15610 stringBuilder.push("</div>",
15611 "<div class='ace_line' style='height:",
15612 this.config.lineHeight, "px'>"
15613 );
15614 }
15615
15616 stringBuilder.push(lang.stringRepeat("\xa0", splits.indent));
15617
15618 split ++;
15619 screenColumn = 0;
15620 splitChars = splits[split] || Number.MAX_VALUE;
15621 }
15622 if (value.length != 0) {
15623 chars += value.length;
15624 screenColumn = this.$renderToken(
15625 stringBuilder, screenColumn, token, value
15626 );
15627 }
15628 }
15629 }
15630 };
15631
15632 this.$renderSimpleLine = function(stringBuilder, tokens) {
15633 var screenColumn = 0;
15634 var token = tokens[0];
15635 var value = token.value;
15636 if (this.displayIndentGuides)
15637 value = this.renderIndentGuide(stringBuilder, value);
15638 if (value)
15639 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15640 for (var i = 1; i < tokens.length; i++) {
15641 token = tokens[i];
15642 value = token.value;
15643 screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
15644 }
15645 };
15646 this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
15647 if (!foldLine && foldLine != false)
15648 foldLine = this.session.getFoldLine(row);
15649
15650 if (foldLine)
15651 var tokens = this.$getFoldLineTokens(row, foldLine);
15652 else
15653 var tokens = this.session.getTokens(row);
15654
15655
15656 if (!onlyContents) {
15657 stringBuilder.push(
15658 "<div class='ace_line' style='height:",
15659 this.config.lineHeight * (
15660 this.$useLineGroups() ? 1 :this.session.getRowLength(row)
15661 ), "px'>"
15662 );
15663 }
15664
15665 if (tokens.length) {
15666 var splits = this.session.getRowSplitData(row);
15667 if (splits && splits.length)
15668 this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
15669 else
15670 this.$renderSimpleLine(stringBuilder, tokens);
15671 }
15672
15673 if (this.showInvisibles) {
15674 if (foldLine)
15675 row = foldLine.end.row;
15676
15677 stringBuilder.push(
15678 "<span class='ace_invisible ace_invisible_eol'>",
15679 row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
15680 "</span>"
15681 );
15682 }
15683 if (!onlyContents)
15684 stringBuilder.push("</div>");
15685 };
15686
15687 this.$getFoldLineTokens = function(row, foldLine) {
15688 var session = this.session;
15689 var renderTokens = [];
15690
15691 function addTokens(tokens, from, to) {
15692 var idx = 0, col = 0;
15693 while ((col + tokens[idx].value.length) < from) {
15694 col += tokens[idx].value.length;
15695 idx++;
15696
15697 if (idx == tokens.length)
15698 return;
15699 }
15700 if (col != from) {
15701 var value = tokens[idx].value.substring(from - col);
15702 if (value.length > (to - from))
15703 value = value.substring(0, to - from);
15704
15705 renderTokens.push({
15706 type: tokens[idx].type,
15707 value: value
15708 });
15709
15710 col = from + value.length;
15711 idx += 1;
15712 }
15713
15714 while (col < to && idx < tokens.length) {
15715 var value = tokens[idx].value;
15716 if (value.length + col > to) {
15717 renderTokens.push({
15718 type: tokens[idx].type,
15719 value: value.substring(0, to - col)
15720 });
15721 } else
15722 renderTokens.push(tokens[idx]);
15723 col += value.length;
15724 idx += 1;
15725 }
15726 }
15727
15728 var tokens = session.getTokens(row);
15729 foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
15730 if (placeholder != null) {
15731 renderTokens.push({
15732 type: "fold",
15733 value: placeholder
15734 });
15735 } else {
15736 if (isNewRow)
15737 tokens = session.getTokens(row);
15738
15739 if (tokens.length)
15740 addTokens(tokens, lastColumn, column);
15741 }
15742 }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
15743
15744 return renderTokens;
15745 };
15746
15747 this.$useLineGroups = function() {
15748 return this.session.getUseWrapMode();
15749 };
15750
15751 this.destroy = function() {
15752 clearInterval(this.$pollSizeChangesTimer);
15753 if (this.$measureNode)
15754 this.$measureNode.parentNode.removeChild(this.$measureNode);
15755 delete this.$measureNode;
15756 };
15757
15758 }).call(Text.prototype);
15759
15760 exports.Text = Text;
15761
15762 });
15763
15764 define("ace/layer/cursor",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
15765 "use strict";
15766
15767 var dom = require("../lib/dom");
15768 var isIE8;
15769
15770 var Cursor = function(parentEl) {
15771 this.element = dom.createElement("div");
15772 this.element.className = "ace_layer ace_cursor-layer";
15773 parentEl.appendChild(this.element);
15774
15775 if (isIE8 === undefined)
15776 isIE8 = !("opacity" in this.element.style);
15777
15778 this.isVisible = false;
15779 this.isBlinking = true;
15780 this.blinkInterval = 1000;
15781 this.smoothBlinking = false;
15782
15783 this.cursors = [];
15784 this.cursor = this.addCursor();
15785 dom.addCssClass(this.element, "ace_hidden-cursors");
15786 this.$updateCursors = (isIE8
15787 ? this.$updateVisibility
15788 : this.$updateOpacity).bind(this);
15789 };
15790
15791 (function() {
15792
15793 this.$updateVisibility = function(val) {
15794 var cursors = this.cursors;
15795 for (var i = cursors.length; i--; )
15796 cursors[i].style.visibility = val ? "" : "hidden";
15797 };
15798 this.$updateOpacity = function(val) {
15799 var cursors = this.cursors;
15800 for (var i = cursors.length; i--; )
15801 cursors[i].style.opacity = val ? "" : "0";
15802 };
15803
15804
15805 this.$padding = 0;
15806 this.setPadding = function(padding) {
15807 this.$padding = padding;
15808 };
15809
15810 this.setSession = function(session) {
15811 this.session = session;
15812 };
15813
15814 this.setBlinking = function(blinking) {
15815 if (blinking != this.isBlinking){
15816 this.isBlinking = blinking;
15817 this.restartTimer();
15818 }
15819 };
15820
15821 this.setBlinkInterval = function(blinkInterval) {
15822 if (blinkInterval != this.blinkInterval){
15823 this.blinkInterval = blinkInterval;
15824 this.restartTimer();
15825 }
15826 };
15827
15828 this.setSmoothBlinking = function(smoothBlinking) {
15829 if (smoothBlinking != this.smoothBlinking && !isIE8) {
15830 this.smoothBlinking = smoothBlinking;
15831 dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking);
15832 this.$updateCursors(true);
15833 this.$updateCursors = (this.$updateOpacity).bind(this);
15834 this.restartTimer();
15835 }
15836 };
15837
15838 this.addCursor = function() {
15839 var el = dom.createElement("div");
15840 el.className = "ace_cursor";
15841 this.element.appendChild(el);
15842 this.cursors.push(el);
15843 return el;
15844 };
15845
15846 this.removeCursor = function() {
15847 if (this.cursors.length > 1) {
15848 var el = this.cursors.pop();
15849 el.parentNode.removeChild(el);
15850 return el;
15851 }
15852 };
15853
15854 this.hideCursor = function() {
15855 this.isVisible = false;
15856 dom.addCssClass(this.element, "ace_hidden-cursors");
15857 this.restartTimer();
15858 };
15859
15860 this.showCursor = function() {
15861 this.isVisible = true;
15862 dom.removeCssClass(this.element, "ace_hidden-cursors");
15863 this.restartTimer();
15864 };
15865
15866 this.restartTimer = function() {
15867 var update = this.$updateCursors;
15868 clearInterval(this.intervalId);
15869 clearTimeout(this.timeoutId);
15870 if (this.smoothBlinking) {
15871 dom.removeCssClass(this.element, "ace_smooth-blinking");
15872 }
15873
15874 update(true);
15875
15876 if (!this.isBlinking || !this.blinkInterval || !this.isVisible)
15877 return;
15878
15879 if (this.smoothBlinking) {
15880 setTimeout(function(){
15881 dom.addCssClass(this.element, "ace_smooth-blinking");
15882 }.bind(this));
15883 }
15884
15885 var blink = function(){
15886 this.timeoutId = setTimeout(function() {
15887 update(false);
15888 }, 0.6 * this.blinkInterval);
15889 }.bind(this);
15890
15891 this.intervalId = setInterval(function() {
15892 update(true);
15893 blink();
15894 }, this.blinkInterval);
15895
15896 blink();
15897 };
15898
15899 this.getPixelPosition = function(position, onScreen) {
15900 if (!this.config || !this.session)
15901 return {left : 0, top : 0};
15902
15903 if (!position)
15904 position = this.session.selection.getCursor();
15905 var pos = this.session.documentToScreenPosition(position);
15906 var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row)
15907 ? this.session.$bidiHandler.getPosLeft(pos.column)
15908 : pos.column * this.config.characterWidth);
15909
15910 var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
15911 this.config.lineHeight;
15912
15913 return {left : cursorLeft, top : cursorTop};
15914 };
15915
15916 this.update = function(config) {
15917 this.config = config;
15918
15919 var selections = this.session.$selectionMarkers;
15920 var i = 0, cursorIndex = 0;
15921
15922 if (selections === undefined || selections.length === 0){
15923 selections = [{cursor: null}];
15924 }
15925
15926 for (var i = 0, n = selections.length; i < n; i++) {
15927 var pixelPos = this.getPixelPosition(selections[i].cursor, true);
15928 if ((pixelPos.top > config.height + config.offset ||
15929 pixelPos.top < 0) && i > 1) {
15930 continue;
15931 }
15932
15933 var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
15934
15935 if (!this.drawCursor) {
15936 style.left = pixelPos.left + "px";
15937 style.top = pixelPos.top + "px";
15938 style.width = config.characterWidth + "px";
15939 style.height = config.lineHeight + "px";
15940 } else {
15941 this.drawCursor(style, pixelPos, config, selections[i], this.session);
15942 }
15943 }
15944 while (this.cursors.length > cursorIndex)
15945 this.removeCursor();
15946
15947 var overwrite = this.session.getOverwrite();
15948 this.$setOverwrite(overwrite);
15949 this.$pixelPos = pixelPos;
15950 this.restartTimer();
15951 };
15952
15953 this.drawCursor = null;
15954
15955 this.$setOverwrite = function(overwrite) {
15956 if (overwrite != this.overwrite) {
15957 this.overwrite = overwrite;
15958 if (overwrite)
15959 dom.addCssClass(this.element, "ace_overwrite-cursors");
15960 else
15961 dom.removeCssClass(this.element, "ace_overwrite-cursors");
15962 }
15963 };
15964
15965 this.destroy = function() {
15966 clearInterval(this.intervalId);
15967 clearTimeout(this.timeoutId);
15968 };
15969
15970 }).call(Cursor.prototype);
15971
15972 exports.Cursor = Cursor;
15973
15974 });
15975
15976 define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"], function(require, exports, module) {
15977 "use strict";
15978
15979 var oop = require("./lib/oop");
15980 var dom = require("./lib/dom");
15981 var event = require("./lib/event");
15982 var EventEmitter = require("./lib/event_emitter").EventEmitter;
15983 var MAX_SCROLL_H = 0x8000;
15984 var ScrollBar = function(parent) {
15985 this.element = dom.createElement("div");
15986 this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix;
15987
15988 this.inner = dom.createElement("div");
15989 this.inner.className = "ace_scrollbar-inner";
15990 this.element.appendChild(this.inner);
15991
15992 parent.appendChild(this.element);
15993
15994 this.setVisible(false);
15995 this.skipEvent = false;
15996
15997 event.addListener(this.element, "scroll", this.onScroll.bind(this));
15998 event.addListener(this.element, "mousedown", event.preventDefault);
15999 };
16000
16001 (function() {
16002 oop.implement(this, EventEmitter);
16003
16004 this.setVisible = function(isVisible) {
16005 this.element.style.display = isVisible ? "" : "none";
16006 this.isVisible = isVisible;
16007 this.coeff = 1;
16008 };
16009 }).call(ScrollBar.prototype);
16010 var VScrollBar = function(parent, renderer) {
16011 ScrollBar.call(this, parent);
16012 this.scrollTop = 0;
16013 this.scrollHeight = 0;
16014 renderer.$scrollbarWidth =
16015 this.width = dom.scrollbarWidth(parent.ownerDocument);
16016 this.inner.style.width =
16017 this.element.style.width = (this.width || 15) + 5 + "px";
16018 this.$minWidth = 0;
16019 };
16020
16021 oop.inherits(VScrollBar, ScrollBar);
16022
16023 (function() {
16024
16025 this.classSuffix = '-v';
16026 this.onScroll = function() {
16027 if (!this.skipEvent) {
16028 this.scrollTop = this.element.scrollTop;
16029 if (this.coeff != 1) {
16030 var h = this.element.clientHeight / this.scrollHeight;
16031 this.scrollTop = this.scrollTop * (1 - h) / (this.coeff - h);
16032 }
16033 this._emit("scroll", {data: this.scrollTop});
16034 }
16035 this.skipEvent = false;
16036 };
16037 this.getWidth = function() {
16038 return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0);
16039 };
16040 this.setHeight = function(height) {
16041 this.element.style.height = height + "px";
16042 };
16043 this.setInnerHeight =
16044 this.setScrollHeight = function(height) {
16045 this.scrollHeight = height;
16046 if (height > MAX_SCROLL_H) {
16047 this.coeff = MAX_SCROLL_H / height;
16048 height = MAX_SCROLL_H;
16049 } else if (this.coeff != 1) {
16050 this.coeff = 1;
16051 }
16052 this.inner.style.height = height + "px";
16053 };
16054 this.setScrollTop = function(scrollTop) {
16055 if (this.scrollTop != scrollTop) {
16056 this.skipEvent = true;
16057 this.scrollTop = scrollTop;
16058 this.element.scrollTop = scrollTop * this.coeff;
16059 }
16060 };
16061
16062 }).call(VScrollBar.prototype);
16063 var HScrollBar = function(parent, renderer) {
16064 ScrollBar.call(this, parent);
16065 this.scrollLeft = 0;
16066 this.height = renderer.$scrollbarWidth;
16067 this.inner.style.height =
16068 this.element.style.height = (this.height || 15) + 5 + "px";
16069 };
16070
16071 oop.inherits(HScrollBar, ScrollBar);
16072
16073 (function() {
16074
16075 this.classSuffix = '-h';
16076 this.onScroll = function() {
16077 if (!this.skipEvent) {
16078 this.scrollLeft = this.element.scrollLeft;
16079 this._emit("scroll", {data: this.scrollLeft});
16080 }
16081 this.skipEvent = false;
16082 };
16083 this.getHeight = function() {
16084 return this.isVisible ? this.height : 0;
16085 };
16086 this.setWidth = function(width) {
16087 this.element.style.width = width + "px";
16088 };
16089 this.setInnerWidth = function(width) {
16090 this.inner.style.width = width + "px";
16091 };
16092 this.setScrollWidth = function(width) {
16093 this.inner.style.width = width + "px";
16094 };
16095 this.setScrollLeft = function(scrollLeft) {
16096 if (this.scrollLeft != scrollLeft) {
16097 this.skipEvent = true;
16098 this.scrollLeft = this.element.scrollLeft = scrollLeft;
16099 }
16100 };
16101
16102 }).call(HScrollBar.prototype);
16103
16104
16105 exports.ScrollBar = VScrollBar; // backward compatibility
16106 exports.ScrollBarV = VScrollBar; // backward compatibility
16107 exports.ScrollBarH = HScrollBar; // backward compatibility
16108
16109 exports.VScrollBar = VScrollBar;
16110 exports.HScrollBar = HScrollBar;
16111 });
16112
16113 define("ace/renderloop",["require","exports","module","ace/lib/event"], function(require, exports, module) {
16114 "use strict";
16115
16116 var event = require("./lib/event");
16117
16118
16119 var RenderLoop = function(onRender, win) {
16120 this.onRender = onRender;
16121 this.pending = false;
16122 this.changes = 0;
16123 this.window = win || window;
16124 };
16125
16126 (function() {
16127
16128
16129 this.schedule = function(change) {
16130 this.changes = this.changes | change;
16131 if (!this.pending && this.changes) {
16132 this.pending = true;
16133 var _self = this;
16134 event.nextFrame(function() {
16135 _self.pending = false;
16136 var changes;
16137 while (changes = _self.changes) {
16138 _self.changes = 0;
16139 _self.onRender(changes);
16140 }
16141 }, this.window);
16142 }
16143 };
16144
16145 }).call(RenderLoop.prototype);
16146
16147 exports.RenderLoop = RenderLoop;
16148 });
16149
16150 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(require, exports, module) {
16151
16152 var oop = require("../lib/oop");
16153 var dom = require("../lib/dom");
16154 var lang = require("../lib/lang");
16155 var useragent = require("../lib/useragent");
16156 var EventEmitter = require("../lib/event_emitter").EventEmitter;
16157
16158 var CHAR_COUNT = 0;
16159
16160 var FontMetrics = exports.FontMetrics = function(parentEl) {
16161 this.el = dom.createElement("div");
16162 this.$setMeasureNodeStyles(this.el.style, true);
16163
16164 this.$main = dom.createElement("div");
16165 this.$setMeasureNodeStyles(this.$main.style);
16166
16167 this.$measureNode = dom.createElement("div");
16168 this.$setMeasureNodeStyles(this.$measureNode.style);
16169
16170
16171 this.el.appendChild(this.$main);
16172 this.el.appendChild(this.$measureNode);
16173 parentEl.appendChild(this.el);
16174
16175 if (!CHAR_COUNT)
16176 this.$testFractionalRect();
16177 this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT);
16178
16179 this.$characterSize = {width: 0, height: 0};
16180 this.checkForSizeChanges();
16181 };
16182
16183 (function() {
16184
16185 oop.implement(this, EventEmitter);
16186
16187 this.$characterSize = {width: 0, height: 0};
16188
16189 this.$testFractionalRect = function() {
16190 var el = dom.createElement("div");
16191 this.$setMeasureNodeStyles(el.style);
16192 el.style.width = "0.2px";
16193 document.documentElement.appendChild(el);
16194 var w = el.getBoundingClientRect().width;
16195 if (w > 0 && w < 1)
16196 CHAR_COUNT = 50;
16197 else
16198 CHAR_COUNT = 100;
16199 el.parentNode.removeChild(el);
16200 };
16201
16202 this.$setMeasureNodeStyles = function(style, isRoot) {
16203 style.width = style.height = "auto";
16204 style.left = style.top = "0px";
16205 style.visibility = "hidden";
16206 style.position = "absolute";
16207 style.whiteSpace = "pre";
16208
16209 if (useragent.isIE < 8) {
16210 style["font-family"] = "inherit";
16211 } else {
16212 style.font = "inherit";
16213 }
16214 style.overflow = isRoot ? "hidden" : "visible";
16215 };
16216
16217 this.checkForSizeChanges = function() {
16218 var size = this.$measureSizes();
16219 if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
16220 this.$measureNode.style.fontWeight = "bold";
16221 var boldSize = this.$measureSizes();
16222 this.$measureNode.style.fontWeight = "";
16223 this.$characterSize = size;
16224 this.charSizes = Object.create(null);
16225 this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
16226 this._emit("changeCharacterSize", {data: size});
16227 }
16228 };
16229
16230 this.$pollSizeChanges = function() {
16231 if (this.$pollSizeChangesTimer)
16232 return this.$pollSizeChangesTimer;
16233 var self = this;
16234 return this.$pollSizeChangesTimer = setInterval(function() {
16235 self.checkForSizeChanges();
16236 }, 500);
16237 };
16238
16239 this.setPolling = function(val) {
16240 if (val) {
16241 this.$pollSizeChanges();
16242 } else if (this.$pollSizeChangesTimer) {
16243 clearInterval(this.$pollSizeChangesTimer);
16244 this.$pollSizeChangesTimer = 0;
16245 }
16246 };
16247
16248 this.$measureSizes = function() {
16249 if (CHAR_COUNT === 50) {
16250 var rect = null;
16251 try {
16252 rect = this.$measureNode.getBoundingClientRect();
16253 } catch(e) {
16254 rect = {width: 0, height:0 };
16255 }
16256 var size = {
16257 height: rect.height,
16258 width: rect.width / CHAR_COUNT
16259 };
16260 } else {
16261 var size = {
16262 height: this.$measureNode.clientHeight,
16263 width: this.$measureNode.clientWidth / CHAR_COUNT
16264 };
16265 }
16266 if (size.width === 0 || size.height === 0)
16267 return null;
16268 return size;
16269 };
16270
16271 this.$measureCharWidth = function(ch) {
16272 this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT);
16273 var rect = this.$main.getBoundingClientRect();
16274 return rect.width / CHAR_COUNT;
16275 };
16276
16277 this.getCharacterWidth = function(ch) {
16278 var w = this.charSizes[ch];
16279 if (w === undefined) {
16280 w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width;
16281 }
16282 return w;
16283 };
16284
16285 this.destroy = function() {
16286 clearInterval(this.$pollSizeChangesTimer);
16287 if (this.el && this.el.parentNode)
16288 this.el.parentNode.removeChild(this.el);
16289 };
16290
16291 }).call(FontMetrics.prototype);
16292
16293 });
16294
16295 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(require, exports, module) {
16296 "use strict";
16297
16298 var oop = require("./lib/oop");
16299 var dom = require("./lib/dom");
16300 var config = require("./config");
16301 var useragent = require("./lib/useragent");
16302 var GutterLayer = require("./layer/gutter").Gutter;
16303 var MarkerLayer = require("./layer/marker").Marker;
16304 var TextLayer = require("./layer/text").Text;
16305 var CursorLayer = require("./layer/cursor").Cursor;
16306 var HScrollBar = require("./scrollbar").HScrollBar;
16307 var VScrollBar = require("./scrollbar").VScrollBar;
16308 var RenderLoop = require("./renderloop").RenderLoop;
16309 var FontMetrics = require("./layer/font_metrics").FontMetrics;
16310 var EventEmitter = require("./lib/event_emitter").EventEmitter;
16311 var editorCss = ".ace_editor {\
16312 position: relative;\
16313 overflow: hidden;\
16314 font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
16315 direction: ltr;\
16316 text-align: left;\
16317 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\
16318 }\
16319 .ace_scroller {\
16320 position: absolute;\
16321 overflow: hidden;\
16322 top: 0;\
16323 bottom: 0;\
16324 background-color: inherit;\
16325 -ms-user-select: none;\
16326 -moz-user-select: none;\
16327 -webkit-user-select: none;\
16328 user-select: none;\
16329 cursor: text;\
16330 }\
16331 .ace_content {\
16332 position: absolute;\
16333 -moz-box-sizing: border-box;\
16334 -webkit-box-sizing: border-box;\
16335 box-sizing: border-box;\
16336 min-width: 100%;\
16337 }\
16338 .ace_dragging .ace_scroller:before{\
16339 position: absolute;\
16340 top: 0;\
16341 left: 0;\
16342 right: 0;\
16343 bottom: 0;\
16344 content: '';\
16345 background: rgba(250, 250, 250, 0.01);\
16346 z-index: 1000;\
16347 }\
16348 .ace_dragging.ace_dark .ace_scroller:before{\
16349 background: rgba(0, 0, 0, 0.01);\
16350 }\
16351 .ace_selecting, .ace_selecting * {\
16352 cursor: text !important;\
16353 }\
16354 .ace_gutter {\
16355 position: absolute;\
16356 overflow : hidden;\
16357 width: auto;\
16358 top: 0;\
16359 bottom: 0;\
16360 left: 0;\
16361 cursor: default;\
16362 z-index: 4;\
16363 -ms-user-select: none;\
16364 -moz-user-select: none;\
16365 -webkit-user-select: none;\
16366 user-select: none;\
16367 }\
16368 .ace_gutter-active-line {\
16369 position: absolute;\
16370 left: 0;\
16371 right: 0;\
16372 }\
16373 .ace_scroller.ace_scroll-left {\
16374 box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\
16375 }\
16376 .ace_gutter-cell {\
16377 padding-left: 19px;\
16378 padding-right: 6px;\
16379 background-repeat: no-repeat;\
16380 }\
16381 .ace_gutter-cell.ace_error {\
16382 background-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==\");\
16383 background-repeat: no-repeat;\
16384 background-position: 2px center;\
16385 }\
16386 .ace_gutter-cell.ace_warning {\
16387 background-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==\");\
16388 background-position: 2px center;\
16389 }\
16390 .ace_gutter-cell.ace_info {\
16391 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\
16392 background-position: 2px center;\
16393 }\
16394 .ace_dark .ace_gutter-cell.ace_info {\
16395 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\
16396 }\
16397 .ace_scrollbar {\
16398 position: absolute;\
16399 right: 0;\
16400 bottom: 0;\
16401 z-index: 6;\
16402 }\
16403 .ace_scrollbar-inner {\
16404 position: absolute;\
16405 cursor: text;\
16406 left: 0;\
16407 top: 0;\
16408 }\
16409 .ace_scrollbar-v{\
16410 overflow-x: hidden;\
16411 overflow-y: scroll;\
16412 top: 0;\
16413 }\
16414 .ace_scrollbar-h {\
16415 overflow-x: scroll;\
16416 overflow-y: hidden;\
16417 left: 0;\
16418 }\
16419 .ace_print-margin {\
16420 position: absolute;\
16421 height: 100%;\
16422 }\
16423 .ace_text-input {\
16424 position: absolute;\
16425 z-index: 0;\
16426 width: 0.5em;\
16427 height: 1em;\
16428 opacity: 0;\
16429 background: transparent;\
16430 -moz-appearance: none;\
16431 appearance: none;\
16432 border: none;\
16433 resize: none;\
16434 outline: none;\
16435 overflow: hidden;\
16436 font: inherit;\
16437 padding: 0 1px;\
16438 margin: 0 -1px;\
16439 text-indent: -1em;\
16440 -ms-user-select: text;\
16441 -moz-user-select: text;\
16442 -webkit-user-select: text;\
16443 user-select: text;\
16444 white-space: pre!important;\
16445 }\
16446 .ace_text-input.ace_composition {\
16447 background: inherit;\
16448 color: inherit;\
16449 z-index: 1000;\
16450 opacity: 1;\
16451 text-indent: 0;\
16452 }\
16453 .ace_layer {\
16454 z-index: 1;\
16455 position: absolute;\
16456 overflow: hidden;\
16457 word-wrap: normal;\
16458 white-space: pre;\
16459 height: 100%;\
16460 width: 100%;\
16461 -moz-box-sizing: border-box;\
16462 -webkit-box-sizing: border-box;\
16463 box-sizing: border-box;\
16464 pointer-events: none;\
16465 }\
16466 .ace_gutter-layer {\
16467 position: relative;\
16468 width: auto;\
16469 text-align: right;\
16470 pointer-events: auto;\
16471 }\
16472 .ace_text-layer {\
16473 font: inherit !important;\
16474 }\
16475 .ace_cjk {\
16476 display: inline-block;\
16477 text-align: center;\
16478 }\
16479 .ace_cursor-layer {\
16480 z-index: 4;\
16481 }\
16482 .ace_cursor {\
16483 z-index: 4;\
16484 position: absolute;\
16485 -moz-box-sizing: border-box;\
16486 -webkit-box-sizing: border-box;\
16487 box-sizing: border-box;\
16488 border-left: 2px solid;\
16489 transform: translatez(0);\
16490 }\
16491 .ace_multiselect .ace_cursor {\
16492 border-left-width: 1px;\
16493 }\
16494 .ace_slim-cursors .ace_cursor {\
16495 border-left-width: 1px;\
16496 }\
16497 .ace_overwrite-cursors .ace_cursor {\
16498 border-left-width: 0;\
16499 border-bottom: 1px solid;\
16500 }\
16501 .ace_hidden-cursors .ace_cursor {\
16502 opacity: 0.2;\
16503 }\
16504 .ace_smooth-blinking .ace_cursor {\
16505 -webkit-transition: opacity 0.18s;\
16506 transition: opacity 0.18s;\
16507 }\
16508 .ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\
16509 position: absolute;\
16510 z-index: 3;\
16511 }\
16512 .ace_marker-layer .ace_selection {\
16513 position: absolute;\
16514 z-index: 5;\
16515 }\
16516 .ace_marker-layer .ace_bracket {\
16517 position: absolute;\
16518 z-index: 6;\
16519 }\
16520 .ace_marker-layer .ace_active-line {\
16521 position: absolute;\
16522 z-index: 2;\
16523 }\
16524 .ace_marker-layer .ace_selected-word {\
16525 position: absolute;\
16526 z-index: 4;\
16527 -moz-box-sizing: border-box;\
16528 -webkit-box-sizing: border-box;\
16529 box-sizing: border-box;\
16530 }\
16531 .ace_line .ace_fold {\
16532 -moz-box-sizing: border-box;\
16533 -webkit-box-sizing: border-box;\
16534 box-sizing: border-box;\
16535 display: inline-block;\
16536 height: 11px;\
16537 margin-top: -2px;\
16538 vertical-align: middle;\
16539 background-image:\
16540 url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
16541 url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\
16542 background-repeat: no-repeat, repeat-x;\
16543 background-position: center center, top left;\
16544 color: transparent;\
16545 border: 1px solid black;\
16546 border-radius: 2px;\
16547 cursor: pointer;\
16548 pointer-events: auto;\
16549 }\
16550 .ace_dark .ace_fold {\
16551 }\
16552 .ace_fold:hover{\
16553 background-image:\
16554 url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
16555 url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\
16556 }\
16557 .ace_tooltip {\
16558 background-color: #FFF;\
16559 background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\
16560 background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\
16561 border: 1px solid gray;\
16562 border-radius: 1px;\
16563 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\
16564 color: black;\
16565 max-width: 100%;\
16566 padding: 3px 4px;\
16567 position: fixed;\
16568 z-index: 999999;\
16569 -moz-box-sizing: border-box;\
16570 -webkit-box-sizing: border-box;\
16571 box-sizing: border-box;\
16572 cursor: default;\
16573 white-space: pre;\
16574 word-wrap: break-word;\
16575 line-height: normal;\
16576 font-style: normal;\
16577 font-weight: normal;\
16578 letter-spacing: normal;\
16579 pointer-events: none;\
16580 }\
16581 .ace_folding-enabled > .ace_gutter-cell {\
16582 padding-right: 13px;\
16583 }\
16584 .ace_fold-widget {\
16585 -moz-box-sizing: border-box;\
16586 -webkit-box-sizing: border-box;\
16587 box-sizing: border-box;\
16588 margin: 0 -12px 0 1px;\
16589 display: none;\
16590 width: 11px;\
16591 vertical-align: top;\
16592 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\
16593 background-repeat: no-repeat;\
16594 background-position: center;\
16595 border-radius: 3px;\
16596 border: 1px solid transparent;\
16597 cursor: pointer;\
16598 }\
16599 .ace_folding-enabled .ace_fold-widget {\
16600 display: inline-block; \
16601 }\
16602 .ace_fold-widget.ace_end {\
16603 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\
16604 }\
16605 .ace_fold-widget.ace_closed {\
16606 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\
16607 }\
16608 .ace_fold-widget:hover {\
16609 border: 1px solid rgba(0, 0, 0, 0.3);\
16610 background-color: rgba(255, 255, 255, 0.2);\
16611 box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
16612 }\
16613 .ace_fold-widget:active {\
16614 border: 1px solid rgba(0, 0, 0, 0.4);\
16615 background-color: rgba(0, 0, 0, 0.05);\
16616 box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
16617 }\
16618 .ace_dark .ace_fold-widget {\
16619 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\
16620 }\
16621 .ace_dark .ace_fold-widget.ace_end {\
16622 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\
16623 }\
16624 .ace_dark .ace_fold-widget.ace_closed {\
16625 background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\
16626 }\
16627 .ace_dark .ace_fold-widget:hover {\
16628 box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
16629 background-color: rgba(255, 255, 255, 0.1);\
16630 }\
16631 .ace_dark .ace_fold-widget:active {\
16632 box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
16633 }\
16634 .ace_fold-widget.ace_invalid {\
16635 background-color: #FFB4B4;\
16636 border-color: #DE5555;\
16637 }\
16638 .ace_fade-fold-widgets .ace_fold-widget {\
16639 -webkit-transition: opacity 0.4s ease 0.05s;\
16640 transition: opacity 0.4s ease 0.05s;\
16641 opacity: 0;\
16642 }\
16643 .ace_fade-fold-widgets:hover .ace_fold-widget {\
16644 -webkit-transition: opacity 0.05s ease 0.05s;\
16645 transition: opacity 0.05s ease 0.05s;\
16646 opacity:1;\
16647 }\
16648 .ace_underline {\
16649 text-decoration: underline;\
16650 }\
16651 .ace_bold {\
16652 font-weight: bold;\
16653 }\
16654 .ace_nobold .ace_bold {\
16655 font-weight: normal;\
16656 }\
16657 .ace_italic {\
16658 font-style: italic;\
16659 }\
16660 .ace_error-marker {\
16661 background-color: rgba(255, 0, 0,0.2);\
16662 position: absolute;\
16663 z-index: 9;\
16664 }\
16665 .ace_highlight-marker {\
16666 background-color: rgba(255, 255, 0,0.2);\
16667 position: absolute;\
16668 z-index: 8;\
16669 }\
16670 .ace_br1 {border-top-left-radius : 3px;}\
16671 .ace_br2 {border-top-right-radius : 3px;}\
16672 .ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}\
16673 .ace_br4 {border-bottom-right-radius: 3px;}\
16674 .ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}\
16675 .ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}\
16676 .ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}\
16677 .ace_br8 {border-bottom-left-radius : 3px;}\
16678 .ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}\
16679 .ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}\
16680 .ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}\
16681 .ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16682 .ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16683 .ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16684 .ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\
16685 .ace_text-input-ios {\
16686 position: absolute !important;\
16687 top: -100000px !important;\
16688 left: -100000px !important;\
16689 }\
16690 ";
16691
16692 dom.importCssString(editorCss, "ace_editor.css");
16693
16694 var VirtualRenderer = function(container, theme) {
16695 var _self = this;
16696
16697 this.container = container || dom.createElement("div");
16698 this.$keepTextAreaAtCursor = !useragent.isOldIE;
16699
16700 dom.addCssClass(this.container, "ace_editor");
16701
16702 this.setTheme(theme);
16703
16704 this.$gutter = dom.createElement("div");
16705 this.$gutter.className = "ace_gutter";
16706 this.container.appendChild(this.$gutter);
16707 this.$gutter.setAttribute("aria-hidden", true);
16708
16709 this.scroller = dom.createElement("div");
16710 this.scroller.className = "ace_scroller";
16711 this.container.appendChild(this.scroller);
16712
16713 this.content = dom.createElement("div");
16714 this.content.className = "ace_content";
16715 this.scroller.appendChild(this.content);
16716
16717 this.$gutterLayer = new GutterLayer(this.$gutter);
16718 this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
16719
16720 this.$markerBack = new MarkerLayer(this.content);
16721
16722 var textLayer = this.$textLayer = new TextLayer(this.content);
16723 this.canvas = textLayer.element;
16724
16725 this.$markerFront = new MarkerLayer(this.content);
16726
16727 this.$cursorLayer = new CursorLayer(this.content);
16728 this.$horizScroll = false;
16729 this.$vScroll = false;
16730
16731 this.scrollBar =
16732 this.scrollBarV = new VScrollBar(this.container, this);
16733 this.scrollBarH = new HScrollBar(this.container, this);
16734 this.scrollBarV.addEventListener("scroll", function(e) {
16735 if (!_self.$scrollAnimation)
16736 _self.session.setScrollTop(e.data - _self.scrollMargin.top);
16737 });
16738 this.scrollBarH.addEventListener("scroll", function(e) {
16739 if (!_self.$scrollAnimation)
16740 _self.session.setScrollLeft(e.data - _self.scrollMargin.left);
16741 });
16742
16743 this.scrollTop = 0;
16744 this.scrollLeft = 0;
16745
16746 this.cursorPos = {
16747 row : 0,
16748 column : 0
16749 };
16750
16751 this.$fontMetrics = new FontMetrics(this.container);
16752 this.$textLayer.$setFontMetrics(this.$fontMetrics);
16753 this.$textLayer.addEventListener("changeCharacterSize", function(e) {
16754 _self.updateCharacterSize();
16755 _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height);
16756 _self._signal("changeCharacterSize", e);
16757 });
16758
16759 this.$size = {
16760 width: 0,
16761 height: 0,
16762 scrollerHeight: 0,
16763 scrollerWidth: 0,
16764 $dirty: true
16765 };
16766
16767 this.layerConfig = {
16768 width : 1,
16769 padding : 0,
16770 firstRow : 0,
16771 firstRowScreen: 0,
16772 lastRow : 0,
16773 lineHeight : 0,
16774 characterWidth : 0,
16775 minHeight : 1,
16776 maxHeight : 1,
16777 offset : 0,
16778 height : 1,
16779 gutterOffset: 1
16780 };
16781
16782 this.scrollMargin = {
16783 left: 0,
16784 right: 0,
16785 top: 0,
16786 bottom: 0,
16787 v: 0,
16788 h: 0
16789 };
16790
16791 this.$loop = new RenderLoop(
16792 this.$renderChanges.bind(this),
16793 this.container.ownerDocument.defaultView
16794 );
16795 this.$loop.schedule(this.CHANGE_FULL);
16796
16797 this.updateCharacterSize();
16798 this.setPadding(4);
16799 config.resetOptions(this);
16800 config._emit("renderer", this);
16801 };
16802
16803 (function() {
16804
16805 this.CHANGE_CURSOR = 1;
16806 this.CHANGE_MARKER = 2;
16807 this.CHANGE_GUTTER = 4;
16808 this.CHANGE_SCROLL = 8;
16809 this.CHANGE_LINES = 16;
16810 this.CHANGE_TEXT = 32;
16811 this.CHANGE_SIZE = 64;
16812 this.CHANGE_MARKER_BACK = 128;
16813 this.CHANGE_MARKER_FRONT = 256;
16814 this.CHANGE_FULL = 512;
16815 this.CHANGE_H_SCROLL = 1024;
16816
16817 oop.implement(this, EventEmitter);
16818
16819 this.updateCharacterSize = function() {
16820 if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {
16821 this.$allowBoldFonts = this.$textLayer.allowBoldFonts;
16822 this.setStyle("ace_nobold", !this.$allowBoldFonts);
16823 }
16824
16825 this.layerConfig.characterWidth =
16826 this.characterWidth = this.$textLayer.getCharacterWidth();
16827 this.layerConfig.lineHeight =
16828 this.lineHeight = this.$textLayer.getLineHeight();
16829 this.$updatePrintMargin();
16830 };
16831 this.setSession = function(session) {
16832 if (this.session)
16833 this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode);
16834
16835 this.session = session;
16836 if (session && this.scrollMargin.top && session.getScrollTop() <= 0)
16837 session.setScrollTop(-this.scrollMargin.top);
16838
16839 this.$cursorLayer.setSession(session);
16840 this.$markerBack.setSession(session);
16841 this.$markerFront.setSession(session);
16842 this.$gutterLayer.setSession(session);
16843 this.$textLayer.setSession(session);
16844 if (!session)
16845 return;
16846
16847 this.$loop.schedule(this.CHANGE_FULL);
16848 this.session.$setFontMetrics(this.$fontMetrics);
16849 this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;
16850
16851 this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);
16852 this.onChangeNewLineMode();
16853 this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode);
16854 };
16855 this.updateLines = function(firstRow, lastRow, force) {
16856 if (lastRow === undefined)
16857 lastRow = Infinity;
16858
16859 if (!this.$changedLines) {
16860 this.$changedLines = {
16861 firstRow: firstRow,
16862 lastRow: lastRow
16863 };
16864 }
16865 else {
16866 if (this.$changedLines.firstRow > firstRow)
16867 this.$changedLines.firstRow = firstRow;
16868
16869 if (this.$changedLines.lastRow < lastRow)
16870 this.$changedLines.lastRow = lastRow;
16871 }
16872 if (this.$changedLines.lastRow < this.layerConfig.firstRow) {
16873 if (force)
16874 this.$changedLines.lastRow = this.layerConfig.lastRow;
16875 else
16876 return;
16877 }
16878 if (this.$changedLines.firstRow > this.layerConfig.lastRow)
16879 return;
16880 this.$loop.schedule(this.CHANGE_LINES);
16881 };
16882
16883 this.onChangeNewLineMode = function() {
16884 this.$loop.schedule(this.CHANGE_TEXT);
16885 this.$textLayer.$updateEolChar();
16886 this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR);
16887 };
16888
16889 this.onChangeTabSize = function() {
16890 this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);
16891 this.$textLayer.onChangeTabSize();
16892 };
16893 this.updateText = function() {
16894 this.$loop.schedule(this.CHANGE_TEXT);
16895 };
16896 this.updateFull = function(force) {
16897 if (force)
16898 this.$renderChanges(this.CHANGE_FULL, true);
16899 else
16900 this.$loop.schedule(this.CHANGE_FULL);
16901 };
16902 this.updateFontSize = function() {
16903 this.$textLayer.checkForSizeChanges();
16904 };
16905
16906 this.$changes = 0;
16907 this.$updateSizeAsync = function() {
16908 if (this.$loop.pending)
16909 this.$size.$dirty = true;
16910 else
16911 this.onResize();
16912 };
16913 this.onResize = function(force, gutterWidth, width, height) {
16914 if (this.resizing > 2)
16915 return;
16916 else if (this.resizing > 0)
16917 this.resizing++;
16918 else
16919 this.resizing = force ? 1 : 0;
16920 var el = this.container;
16921 if (!height)
16922 height = el.clientHeight || el.scrollHeight;
16923 if (!width)
16924 width = el.clientWidth || el.scrollWidth;
16925 var changes = this.$updateCachedSize(force, gutterWidth, width, height);
16926
16927
16928 if (!this.$size.scrollerHeight || (!width && !height))
16929 return this.resizing = 0;
16930
16931 if (force)
16932 this.$gutterLayer.$padding = null;
16933
16934 if (force)
16935 this.$renderChanges(changes | this.$changes, true);
16936 else
16937 this.$loop.schedule(changes | this.$changes);
16938
16939 if (this.resizing)
16940 this.resizing = 0;
16941 this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null;
16942 };
16943
16944 this.$updateCachedSize = function(force, gutterWidth, width, height) {
16945 height -= (this.$extraHeight || 0);
16946 var changes = 0;
16947 var size = this.$size;
16948 var oldSize = {
16949 width: size.width,
16950 height: size.height,
16951 scrollerHeight: size.scrollerHeight,
16952 scrollerWidth: size.scrollerWidth
16953 };
16954 if (height && (force || size.height != height)) {
16955 size.height = height;
16956 changes |= this.CHANGE_SIZE;
16957
16958 size.scrollerHeight = size.height;
16959 if (this.$horizScroll)
16960 size.scrollerHeight -= this.scrollBarH.getHeight();
16961 this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px";
16962
16963 changes = changes | this.CHANGE_SCROLL;
16964 }
16965
16966 if (width && (force || size.width != width)) {
16967 changes |= this.CHANGE_SIZE;
16968 size.width = width;
16969
16970 if (gutterWidth == null)
16971 gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
16972
16973 this.gutterWidth = gutterWidth;
16974
16975 this.scrollBarH.element.style.left =
16976 this.scroller.style.left = gutterWidth + "px";
16977 size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());
16978
16979 this.scrollBarH.element.style.right =
16980 this.scroller.style.right = this.scrollBarV.getWidth() + "px";
16981 this.scroller.style.bottom = this.scrollBarH.getHeight() + "px";
16982
16983 if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
16984 changes |= this.CHANGE_FULL;
16985 }
16986
16987 size.$dirty = !width || !height;
16988
16989 if (changes)
16990 this._signal("resize", oldSize);
16991
16992 return changes;
16993 };
16994
16995 this.onGutterResize = function() {
16996 var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
16997 if (gutterWidth != this.gutterWidth)
16998 this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
16999
17000 if (this.session.getUseWrapMode() && this.adjustWrapLimit()) {
17001 this.$loop.schedule(this.CHANGE_FULL);
17002 } else if (this.$size.$dirty) {
17003 this.$loop.schedule(this.CHANGE_FULL);
17004 } else {
17005 this.$computeLayerConfig();
17006 this.$loop.schedule(this.CHANGE_MARKER);
17007 }
17008 };
17009 this.adjustWrapLimit = function() {
17010 var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
17011 var limit = Math.floor(availableWidth / this.characterWidth);
17012 return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn);
17013 };
17014 this.setAnimatedScroll = function(shouldAnimate){
17015 this.setOption("animatedScroll", shouldAnimate);
17016 };
17017 this.getAnimatedScroll = function() {
17018 return this.$animatedScroll;
17019 };
17020 this.setShowInvisibles = function(showInvisibles) {
17021 this.setOption("showInvisibles", showInvisibles);
17022 this.session.$bidiHandler.setShowInvisibles(showInvisibles);
17023 };
17024 this.getShowInvisibles = function() {
17025 return this.getOption("showInvisibles");
17026 };
17027 this.getDisplayIndentGuides = function() {
17028 return this.getOption("displayIndentGuides");
17029 };
17030
17031 this.setDisplayIndentGuides = function(display) {
17032 this.setOption("displayIndentGuides", display);
17033 };
17034 this.setShowPrintMargin = function(showPrintMargin) {
17035 this.setOption("showPrintMargin", showPrintMargin);
17036 };
17037 this.getShowPrintMargin = function() {
17038 return this.getOption("showPrintMargin");
17039 };
17040 this.setPrintMarginColumn = function(showPrintMargin) {
17041 this.setOption("printMarginColumn", showPrintMargin);
17042 };
17043 this.getPrintMarginColumn = function() {
17044 return this.getOption("printMarginColumn");
17045 };
17046 this.getShowGutter = function(){
17047 return this.getOption("showGutter");
17048 };
17049 this.setShowGutter = function(show){
17050 return this.setOption("showGutter", show);
17051 };
17052
17053 this.getFadeFoldWidgets = function(){
17054 return this.getOption("fadeFoldWidgets");
17055 };
17056
17057 this.setFadeFoldWidgets = function(show) {
17058 this.setOption("fadeFoldWidgets", show);
17059 };
17060
17061 this.setHighlightGutterLine = function(shouldHighlight) {
17062 this.setOption("highlightGutterLine", shouldHighlight);
17063 };
17064
17065 this.getHighlightGutterLine = function() {
17066 return this.getOption("highlightGutterLine");
17067 };
17068
17069 this.$updateGutterLineHighlight = function() {
17070 var pos = this.$cursorLayer.$pixelPos;
17071 var height = this.layerConfig.lineHeight;
17072 if (this.session.getUseWrapMode()) {
17073 var cursor = this.session.selection.getCursor();
17074 cursor.column = 0;
17075 pos = this.$cursorLayer.getPixelPosition(cursor, true);
17076 height *= this.session.getRowLength(cursor.row);
17077 }
17078 this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px";
17079 this.$gutterLineHighlight.style.height = height + "px";
17080 };
17081
17082 this.$updatePrintMargin = function() {
17083 if (!this.$showPrintMargin && !this.$printMarginEl)
17084 return;
17085
17086 if (!this.$printMarginEl) {
17087 var containerEl = dom.createElement("div");
17088 containerEl.className = "ace_layer ace_print-margin-layer";
17089 this.$printMarginEl = dom.createElement("div");
17090 this.$printMarginEl.className = "ace_print-margin";
17091 containerEl.appendChild(this.$printMarginEl);
17092 this.content.insertBefore(containerEl, this.content.firstChild);
17093 }
17094
17095 var style = this.$printMarginEl.style;
17096 style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px";
17097 style.visibility = this.$showPrintMargin ? "visible" : "hidden";
17098
17099 if (this.session && this.session.$wrap == -1)
17100 this.adjustWrapLimit();
17101 };
17102 this.getContainerElement = function() {
17103 return this.container;
17104 };
17105 this.getMouseEventTarget = function() {
17106 return this.scroller;
17107 };
17108 this.getTextAreaContainer = function() {
17109 return this.container;
17110 };
17111 this.$moveTextAreaToCursor = function() {
17112 if (!this.$keepTextAreaAtCursor)
17113 return;
17114 var config = this.layerConfig;
17115 var posTop = this.$cursorLayer.$pixelPos.top;
17116 var posLeft = this.$cursorLayer.$pixelPos.left;
17117 posTop -= config.offset;
17118
17119 var style = this.textarea.style;
17120 var h = this.lineHeight;
17121 if (posTop < 0 || posTop > config.height - h) {
17122 style.top = style.left = "0";
17123 return;
17124 }
17125
17126 var w = this.characterWidth;
17127 if (this.$composition) {
17128 var val = this.textarea.value.replace(/^\x01+/, "");
17129 w *= (this.session.$getStringScreenWidth(val)[0]+2);
17130 h += 2;
17131 }
17132 posLeft -= this.scrollLeft;
17133 if (posLeft > this.$size.scrollerWidth - w)
17134 posLeft = this.$size.scrollerWidth - w;
17135
17136 posLeft += this.gutterWidth;
17137 style.height = h + "px";
17138 style.width = w + "px";
17139 style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + "px";
17140 style.top = Math.min(posTop, this.$size.height - h) + "px";
17141 };
17142 this.getFirstVisibleRow = function() {
17143 return this.layerConfig.firstRow;
17144 };
17145 this.getFirstFullyVisibleRow = function() {
17146 return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
17147 };
17148 this.getLastFullyVisibleRow = function() {
17149 var config = this.layerConfig;
17150 var lastRow = config.lastRow;
17151 var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight;
17152 if (top - this.session.getScrollTop() > config.height - config.lineHeight)
17153 return lastRow - 1;
17154 return lastRow;
17155 };
17156 this.getLastVisibleRow = function() {
17157 return this.layerConfig.lastRow;
17158 };
17159
17160 this.$padding = null;
17161 this.setPadding = function(padding) {
17162 this.$padding = padding;
17163 this.$textLayer.setPadding(padding);
17164 this.$cursorLayer.setPadding(padding);
17165 this.$markerFront.setPadding(padding);
17166 this.$markerBack.setPadding(padding);
17167 this.$loop.schedule(this.CHANGE_FULL);
17168 this.$updatePrintMargin();
17169 };
17170
17171 this.setScrollMargin = function(top, bottom, left, right) {
17172 var sm = this.scrollMargin;
17173 sm.top = top|0;
17174 sm.bottom = bottom|0;
17175 sm.right = right|0;
17176 sm.left = left|0;
17177 sm.v = sm.top + sm.bottom;
17178 sm.h = sm.left + sm.right;
17179 if (sm.top && this.scrollTop <= 0 && this.session)
17180 this.session.setScrollTop(-sm.top);
17181 this.updateFull();
17182 };
17183 this.getHScrollBarAlwaysVisible = function() {
17184 return this.$hScrollBarAlwaysVisible;
17185 };
17186 this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
17187 this.setOption("hScrollBarAlwaysVisible", alwaysVisible);
17188 };
17189 this.getVScrollBarAlwaysVisible = function() {
17190 return this.$vScrollBarAlwaysVisible;
17191 };
17192 this.setVScrollBarAlwaysVisible = function(alwaysVisible) {
17193 this.setOption("vScrollBarAlwaysVisible", alwaysVisible);
17194 };
17195
17196 this.$updateScrollBarV = function() {
17197 var scrollHeight = this.layerConfig.maxHeight;
17198 var scrollerHeight = this.$size.scrollerHeight;
17199 if (!this.$maxLines && this.$scrollPastEnd) {
17200 scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd;
17201 if (this.scrollTop > scrollHeight - scrollerHeight) {
17202 scrollHeight = this.scrollTop + scrollerHeight;
17203 this.scrollBarV.scrollTop = null;
17204 }
17205 }
17206 this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v);
17207 this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);
17208 };
17209 this.$updateScrollBarH = function() {
17210 this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);
17211 this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);
17212 };
17213
17214 this.$frozen = false;
17215 this.freeze = function() {
17216 this.$frozen = true;
17217 };
17218
17219 this.unfreeze = function() {
17220 this.$frozen = false;
17221 };
17222
17223 this.$renderChanges = function(changes, force) {
17224 if (this.$changes) {
17225 changes |= this.$changes;
17226 this.$changes = 0;
17227 }
17228 if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) {
17229 this.$changes |= changes;
17230 return;
17231 }
17232 if (this.$size.$dirty) {
17233 this.$changes |= changes;
17234 return this.onResize(true);
17235 }
17236 if (!this.lineHeight) {
17237 this.$textLayer.checkForSizeChanges();
17238 }
17239
17240 this._signal("beforeRender");
17241
17242 if (this.session && this.session.$bidiHandler)
17243 this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);
17244
17245 var config = this.layerConfig;
17246 if (changes & this.CHANGE_FULL ||
17247 changes & this.CHANGE_SIZE ||
17248 changes & this.CHANGE_TEXT ||
17249 changes & this.CHANGE_LINES ||
17250 changes & this.CHANGE_SCROLL ||
17251 changes & this.CHANGE_H_SCROLL
17252 ) {
17253 changes |= this.$computeLayerConfig();
17254 if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) {
17255 var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight;
17256 if (st > 0) {
17257 this.scrollTop = st;
17258 changes = changes | this.CHANGE_SCROLL;
17259 changes |= this.$computeLayerConfig();
17260 }
17261 }
17262 config = this.layerConfig;
17263 this.$updateScrollBarV();
17264 if (changes & this.CHANGE_H_SCROLL)
17265 this.$updateScrollBarH();
17266 this.$gutterLayer.element.style.marginTop = (-config.offset) + "px";
17267 this.content.style.marginTop = (-config.offset) + "px";
17268 this.content.style.width = config.width + 2 * this.$padding + "px";
17269 this.content.style.height = config.minHeight + "px";
17270 }
17271 if (changes & this.CHANGE_H_SCROLL) {
17272 this.content.style.marginLeft = -this.scrollLeft + "px";
17273 this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
17274 }
17275 if (changes & this.CHANGE_FULL) {
17276 this.$textLayer.update(config);
17277 if (this.$showGutter)
17278 this.$gutterLayer.update(config);
17279 this.$markerBack.update(config);
17280 this.$markerFront.update(config);
17281 this.$cursorLayer.update(config);
17282 this.$moveTextAreaToCursor();
17283 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17284 this._signal("afterRender");
17285 return;
17286 }
17287 if (changes & this.CHANGE_SCROLL) {
17288 if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
17289 this.$textLayer.update(config);
17290 else
17291 this.$textLayer.scrollLines(config);
17292
17293 if (this.$showGutter)
17294 this.$gutterLayer.update(config);
17295 this.$markerBack.update(config);
17296 this.$markerFront.update(config);
17297 this.$cursorLayer.update(config);
17298 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17299 this.$moveTextAreaToCursor();
17300 this._signal("afterRender");
17301 return;
17302 }
17303
17304 if (changes & this.CHANGE_TEXT) {
17305 this.$textLayer.update(config);
17306 if (this.$showGutter)
17307 this.$gutterLayer.update(config);
17308 }
17309 else if (changes & this.CHANGE_LINES) {
17310 if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
17311 this.$gutterLayer.update(config);
17312 }
17313 else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
17314 if (this.$showGutter)
17315 this.$gutterLayer.update(config);
17316 }
17317
17318 if (changes & this.CHANGE_CURSOR) {
17319 this.$cursorLayer.update(config);
17320 this.$moveTextAreaToCursor();
17321 this.$highlightGutterLine && this.$updateGutterLineHighlight();
17322 }
17323
17324 if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
17325 this.$markerFront.update(config);
17326 }
17327
17328 if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
17329 this.$markerBack.update(config);
17330 }
17331
17332 this._signal("afterRender");
17333 };
17334
17335
17336 this.$autosize = function() {
17337 var height = this.session.getScreenLength() * this.lineHeight;
17338 var maxHeight = this.$maxLines * this.lineHeight;
17339 var desiredHeight = Math.min(maxHeight,
17340 Math.max((this.$minLines || 1) * this.lineHeight, height)
17341 ) + this.scrollMargin.v + (this.$extraHeight || 0);
17342 if (this.$horizScroll)
17343 desiredHeight += this.scrollBarH.getHeight();
17344 if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight)
17345 desiredHeight = this.$maxPixelHeight;
17346 var vScroll = height > maxHeight;
17347
17348 if (desiredHeight != this.desiredHeight ||
17349 this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {
17350 if (vScroll != this.$vScroll) {
17351 this.$vScroll = vScroll;
17352 this.scrollBarV.setVisible(vScroll);
17353 }
17354
17355 var w = this.container.clientWidth;
17356 this.container.style.height = desiredHeight + "px";
17357 this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);
17358 this.desiredHeight = desiredHeight;
17359
17360 this._signal("autosize");
17361 }
17362 };
17363
17364 this.$computeLayerConfig = function() {
17365 var session = this.session;
17366 var size = this.$size;
17367
17368 var hideScrollbars = size.height <= 2 * this.lineHeight;
17369 var screenLines = this.session.getScreenLength();
17370 var maxHeight = screenLines * this.lineHeight;
17371
17372 var longestLine = this.$getLongestLine();
17373
17374 var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||
17375 size.scrollerWidth - longestLine - 2 * this.$padding < 0);
17376
17377 var hScrollChanged = this.$horizScroll !== horizScroll;
17378 if (hScrollChanged) {
17379 this.$horizScroll = horizScroll;
17380 this.scrollBarH.setVisible(horizScroll);
17381 }
17382 var vScrollBefore = this.$vScroll; // autosize can change vscroll value in which case we need to update longestLine
17383 if (this.$maxLines && this.lineHeight > 1)
17384 this.$autosize();
17385
17386 var offset = this.scrollTop % this.lineHeight;
17387 var minHeight = size.scrollerHeight + this.lineHeight;
17388
17389 var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd
17390 ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd
17391 : 0;
17392 maxHeight += scrollPastEnd;
17393
17394 var sm = this.scrollMargin;
17395 this.session.setScrollTop(Math.max(-sm.top,
17396 Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom)));
17397
17398 this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft,
17399 longestLine + 2 * this.$padding - size.scrollerWidth + sm.right)));
17400
17401 var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||
17402 size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top);
17403 var vScrollChanged = vScrollBefore !== vScroll;
17404 if (vScrollChanged) {
17405 this.$vScroll = vScroll;
17406 this.scrollBarV.setVisible(vScroll);
17407 }
17408
17409 var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
17410 var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
17411 var lastRow = firstRow + lineCount;
17412 var firstRowScreen, firstRowHeight;
17413 var lineHeight = this.lineHeight;
17414 firstRow = session.screenToDocumentRow(firstRow, 0);
17415 var foldLine = session.getFoldLine(firstRow);
17416 if (foldLine) {
17417 firstRow = foldLine.start.row;
17418 }
17419
17420 firstRowScreen = session.documentToScreenRow(firstRow, 0);
17421 firstRowHeight = session.getRowLength(firstRow) * lineHeight;
17422
17423 lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);
17424 minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +
17425 firstRowHeight;
17426
17427 offset = this.scrollTop - firstRowScreen * lineHeight;
17428
17429 var changes = 0;
17430 if (this.layerConfig.width != longestLine)
17431 changes = this.CHANGE_H_SCROLL;
17432 if (hScrollChanged || vScrollChanged) {
17433 changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height);
17434 this._signal("scrollbarVisibilityChanged");
17435 if (vScrollChanged)
17436 longestLine = this.$getLongestLine();
17437 }
17438
17439 this.layerConfig = {
17440 width : longestLine,
17441 padding : this.$padding,
17442 firstRow : firstRow,
17443 firstRowScreen: firstRowScreen,
17444 lastRow : lastRow,
17445 lineHeight : lineHeight,
17446 characterWidth : this.characterWidth,
17447 minHeight : minHeight,
17448 maxHeight : maxHeight,
17449 offset : offset,
17450 gutterOffset : lineHeight ? Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)) : 0,
17451 height : this.$size.scrollerHeight
17452 };
17453
17454 return changes;
17455 };
17456
17457 this.$updateLines = function() {
17458 if (!this.$changedLines) return;
17459 var firstRow = this.$changedLines.firstRow;
17460 var lastRow = this.$changedLines.lastRow;
17461 this.$changedLines = null;
17462
17463 var layerConfig = this.layerConfig;
17464
17465 if (firstRow > layerConfig.lastRow + 1) { return; }
17466 if (lastRow < layerConfig.firstRow) { return; }
17467 if (lastRow === Infinity) {
17468 if (this.$showGutter)
17469 this.$gutterLayer.update(layerConfig);
17470 this.$textLayer.update(layerConfig);
17471 return;
17472 }
17473 this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
17474 return true;
17475 };
17476
17477 this.$getLongestLine = function() {
17478 var charCount = this.session.getScreenWidth();
17479 if (this.showInvisibles && !this.session.$useWrapMode)
17480 charCount += 1;
17481
17482 return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
17483 };
17484 this.updateFrontMarkers = function() {
17485 this.$markerFront.setMarkers(this.session.getMarkers(true));
17486 this.$loop.schedule(this.CHANGE_MARKER_FRONT);
17487 };
17488 this.updateBackMarkers = function() {
17489 this.$markerBack.setMarkers(this.session.getMarkers());
17490 this.$loop.schedule(this.CHANGE_MARKER_BACK);
17491 };
17492 this.addGutterDecoration = function(row, className){
17493 this.$gutterLayer.addGutterDecoration(row, className);
17494 };
17495 this.removeGutterDecoration = function(row, className){
17496 this.$gutterLayer.removeGutterDecoration(row, className);
17497 };
17498 this.updateBreakpoints = function(rows) {
17499 this.$loop.schedule(this.CHANGE_GUTTER);
17500 };
17501 this.setAnnotations = function(annotations) {
17502 this.$gutterLayer.setAnnotations(annotations);
17503 this.$loop.schedule(this.CHANGE_GUTTER);
17504 };
17505 this.updateCursor = function() {
17506 this.$loop.schedule(this.CHANGE_CURSOR);
17507 };
17508 this.hideCursor = function() {
17509 this.$cursorLayer.hideCursor();
17510 };
17511 this.showCursor = function() {
17512 this.$cursorLayer.showCursor();
17513 };
17514
17515 this.scrollSelectionIntoView = function(anchor, lead, offset) {
17516 this.scrollCursorIntoView(anchor, offset);
17517 this.scrollCursorIntoView(lead, offset);
17518 };
17519 this.scrollCursorIntoView = function(cursor, offset, $viewMargin) {
17520 if (this.$size.scrollerHeight === 0)
17521 return;
17522
17523 var pos = this.$cursorLayer.getPixelPosition(cursor);
17524
17525 var left = pos.left;
17526 var top = pos.top;
17527
17528 var topMargin = $viewMargin && $viewMargin.top || 0;
17529 var bottomMargin = $viewMargin && $viewMargin.bottom || 0;
17530
17531 var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
17532
17533 if (scrollTop + topMargin > top) {
17534 if (offset && scrollTop + topMargin > top + this.lineHeight)
17535 top -= offset * this.$size.scrollerHeight;
17536 if (top === 0)
17537 top = -this.scrollMargin.top;
17538 this.session.setScrollTop(top);
17539 } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) {
17540 if (offset && scrollTop + this.$size.scrollerHeight - bottomMargin < top - this.lineHeight)
17541 top += offset * this.$size.scrollerHeight;
17542 this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
17543 }
17544
17545 var scrollLeft = this.scrollLeft;
17546
17547 if (scrollLeft > left) {
17548 if (left < this.$padding + 2 * this.layerConfig.characterWidth)
17549 left = -this.scrollMargin.left;
17550 this.session.setScrollLeft(left);
17551 } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
17552 this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
17553 } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {
17554 this.session.setScrollLeft(0);
17555 }
17556 };
17557 this.getScrollTop = function() {
17558 return this.session.getScrollTop();
17559 };
17560 this.getScrollLeft = function() {
17561 return this.session.getScrollLeft();
17562 };
17563 this.getScrollTopRow = function() {
17564 return this.scrollTop / this.lineHeight;
17565 };
17566 this.getScrollBottomRow = function() {
17567 return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
17568 };
17569 this.scrollToRow = function(row) {
17570 this.session.setScrollTop(row * this.lineHeight);
17571 };
17572
17573 this.alignCursor = function(cursor, alignment) {
17574 if (typeof cursor == "number")
17575 cursor = {row: cursor, column: 0};
17576
17577 var pos = this.$cursorLayer.getPixelPosition(cursor);
17578 var h = this.$size.scrollerHeight - this.lineHeight;
17579 var offset = pos.top - h * (alignment || 0);
17580
17581 this.session.setScrollTop(offset);
17582 return offset;
17583 };
17584
17585 this.STEPS = 8;
17586 this.$calcSteps = function(fromValue, toValue){
17587 var i = 0;
17588 var l = this.STEPS;
17589 var steps = [];
17590
17591 var func = function(t, x_min, dx) {
17592 return dx * (Math.pow(t - 1, 3) + 1) + x_min;
17593 };
17594
17595 for (i = 0; i < l; ++i)
17596 steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
17597
17598 return steps;
17599 };
17600 this.scrollToLine = function(line, center, animate, callback) {
17601 var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
17602 var offset = pos.top;
17603 if (center)
17604 offset -= this.$size.scrollerHeight / 2;
17605
17606 var initialScroll = this.scrollTop;
17607 this.session.setScrollTop(offset);
17608 if (animate !== false)
17609 this.animateScrolling(initialScroll, callback);
17610 };
17611
17612 this.animateScrolling = function(fromValue, callback) {
17613 var toValue = this.scrollTop;
17614 if (!this.$animatedScroll)
17615 return;
17616 var _self = this;
17617
17618 if (fromValue == toValue)
17619 return;
17620
17621 if (this.$scrollAnimation) {
17622 var oldSteps = this.$scrollAnimation.steps;
17623 if (oldSteps.length) {
17624 fromValue = oldSteps[0];
17625 if (fromValue == toValue)
17626 return;
17627 }
17628 }
17629
17630 var steps = _self.$calcSteps(fromValue, toValue);
17631 this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};
17632
17633 clearInterval(this.$timer);
17634
17635 _self.session.setScrollTop(steps.shift());
17636 _self.session.$scrollTop = toValue;
17637 this.$timer = setInterval(function() {
17638 if (steps.length) {
17639 _self.session.setScrollTop(steps.shift());
17640 _self.session.$scrollTop = toValue;
17641 } else if (toValue != null) {
17642 _self.session.$scrollTop = -1;
17643 _self.session.setScrollTop(toValue);
17644 toValue = null;
17645 } else {
17646 _self.$timer = clearInterval(_self.$timer);
17647 _self.$scrollAnimation = null;
17648 callback && callback();
17649 }
17650 }, 10);
17651 };
17652 this.scrollToY = function(scrollTop) {
17653 if (this.scrollTop !== scrollTop) {
17654 this.$loop.schedule(this.CHANGE_SCROLL);
17655 this.scrollTop = scrollTop;
17656 }
17657 };
17658 this.scrollToX = function(scrollLeft) {
17659 if (this.scrollLeft !== scrollLeft)
17660 this.scrollLeft = scrollLeft;
17661 this.$loop.schedule(this.CHANGE_H_SCROLL);
17662 };
17663 this.scrollTo = function(x, y) {
17664 this.session.setScrollTop(y);
17665 this.session.setScrollLeft(y);
17666 };
17667 this.scrollBy = function(deltaX, deltaY) {
17668 deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
17669 deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
17670 };
17671 this.isScrollableBy = function(deltaX, deltaY) {
17672 if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)
17673 return true;
17674 if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight
17675 - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)
17676 return true;
17677 if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left)
17678 return true;
17679 if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth
17680 - this.layerConfig.width < -1 + this.scrollMargin.right)
17681 return true;
17682 };
17683
17684 this.pixelToScreenCoordinates = function(x, y) {
17685 var canvasPos = this.scroller.getBoundingClientRect();
17686
17687 var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;
17688 var offset = offsetX / this.characterWidth;
17689 var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
17690 var col = Math.round(offset);
17691
17692 return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX: offsetX};
17693 };
17694
17695 this.screenToTextCoordinates = function(x, y) {
17696 var canvasPos = this.scroller.getBoundingClientRect();
17697 var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;
17698
17699 var col = Math.round(offsetX / this.characterWidth);
17700
17701 var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight;
17702
17703 return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX);
17704 };
17705 this.textToScreenCoordinates = function(row, column) {
17706 var canvasPos = this.scroller.getBoundingClientRect();
17707 var pos = this.session.documentToScreenPosition(row, column);
17708
17709 var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row)
17710 ? this.session.$bidiHandler.getPosLeft(pos.column)
17711 : Math.round(pos.column * this.characterWidth));
17712
17713 var y = pos.row * this.lineHeight;
17714
17715 return {
17716 pageX: canvasPos.left + x - this.scrollLeft,
17717 pageY: canvasPos.top + y - this.scrollTop
17718 };
17719 };
17720 this.visualizeFocus = function() {
17721 dom.addCssClass(this.container, "ace_focus");
17722 };
17723 this.visualizeBlur = function() {
17724 dom.removeCssClass(this.container, "ace_focus");
17725 };
17726 this.showComposition = function(position) {
17727 if (!this.$composition)
17728 this.$composition = {
17729 keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
17730 cssText: this.textarea.style.cssText
17731 };
17732
17733 this.$keepTextAreaAtCursor = true;
17734 dom.addCssClass(this.textarea, "ace_composition");
17735 this.textarea.style.cssText = "";
17736 this.$moveTextAreaToCursor();
17737 };
17738 this.setCompositionText = function(text) {
17739 this.$moveTextAreaToCursor();
17740 };
17741 this.hideComposition = function() {
17742 if (!this.$composition)
17743 return;
17744
17745 dom.removeCssClass(this.textarea, "ace_composition");
17746 this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;
17747 this.textarea.style.cssText = this.$composition.cssText;
17748 this.$composition = null;
17749 };
17750 this.setTheme = function(theme, cb) {
17751 var _self = this;
17752 this.$themeId = theme;
17753 _self._dispatchEvent('themeChange',{theme:theme});
17754
17755 if (!theme || typeof theme == "string") {
17756 var moduleName = theme || this.$options.theme.initialValue;
17757 config.loadModule(["theme", moduleName], afterLoad);
17758 } else {
17759 afterLoad(theme);
17760 }
17761
17762 function afterLoad(module) {
17763 if (_self.$themeId != theme)
17764 return cb && cb();
17765 if (!module || !module.cssClass)
17766 throw new Error("couldn't load module " + theme + " or it didn't call define");
17767 dom.importCssString(
17768 module.cssText,
17769 module.cssClass,
17770 _self.container.ownerDocument
17771 );
17772
17773 if (_self.theme)
17774 dom.removeCssClass(_self.container, _self.theme.cssClass);
17775
17776 var padding = "padding" in module ? module.padding
17777 : "padding" in (_self.theme || {}) ? 4 : _self.$padding;
17778 if (_self.$padding && padding != _self.$padding)
17779 _self.setPadding(padding);
17780 _self.$theme = module.cssClass;
17781
17782 _self.theme = module;
17783 dom.addCssClass(_self.container, module.cssClass);
17784 dom.setCssClass(_self.container, "ace_dark", module.isDark);
17785 if (_self.$size) {
17786 _self.$size.width = 0;
17787 _self.$updateSizeAsync();
17788 }
17789
17790 _self._dispatchEvent('themeLoaded', {theme:module});
17791 cb && cb();
17792 }
17793 };
17794 this.getTheme = function() {
17795 return this.$themeId;
17796 };
17797 this.setStyle = function(style, include) {
17798 dom.setCssClass(this.container, style, include !== false);
17799 };
17800 this.unsetStyle = function(style) {
17801 dom.removeCssClass(this.container, style);
17802 };
17803
17804 this.setCursorStyle = function(style) {
17805 if (this.scroller.style.cursor != style)
17806 this.scroller.style.cursor = style;
17807 };
17808 this.setMouseCursor = function(cursorStyle) {
17809 this.scroller.style.cursor = cursorStyle;
17810 };
17811 this.destroy = function() {
17812 this.$textLayer.destroy();
17813 this.$cursorLayer.destroy();
17814 };
17815
17816 }).call(VirtualRenderer.prototype);
17817
17818
17819 config.defineOptions(VirtualRenderer.prototype, "renderer", {
17820 animatedScroll: {initialValue: false},
17821 showInvisibles: {
17822 set: function(value) {
17823 if (this.$textLayer.setShowInvisibles(value))
17824 this.$loop.schedule(this.CHANGE_TEXT);
17825 },
17826 initialValue: false
17827 },
17828 showPrintMargin: {
17829 set: function() { this.$updatePrintMargin(); },
17830 initialValue: true
17831 },
17832 printMarginColumn: {
17833 set: function() { this.$updatePrintMargin(); },
17834 initialValue: 80
17835 },
17836 printMargin: {
17837 set: function(val) {
17838 if (typeof val == "number")
17839 this.$printMarginColumn = val;
17840 this.$showPrintMargin = !!val;
17841 this.$updatePrintMargin();
17842 },
17843 get: function() {
17844 return this.$showPrintMargin && this.$printMarginColumn;
17845 }
17846 },
17847 showGutter: {
17848 set: function(show){
17849 this.$gutter.style.display = show ? "block" : "none";
17850 this.$loop.schedule(this.CHANGE_FULL);
17851 this.onGutterResize();
17852 },
17853 initialValue: true
17854 },
17855 fadeFoldWidgets: {
17856 set: function(show) {
17857 dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
17858 },
17859 initialValue: false
17860 },
17861 showFoldWidgets: {
17862 set: function(show) {this.$gutterLayer.setShowFoldWidgets(show);},
17863 initialValue: true
17864 },
17865 showLineNumbers: {
17866 set: function(show) {
17867 this.$gutterLayer.setShowLineNumbers(show);
17868 this.$loop.schedule(this.CHANGE_GUTTER);
17869 },
17870 initialValue: true
17871 },
17872 displayIndentGuides: {
17873 set: function(show) {
17874 if (this.$textLayer.setDisplayIndentGuides(show))
17875 this.$loop.schedule(this.CHANGE_TEXT);
17876 },
17877 initialValue: true
17878 },
17879 highlightGutterLine: {
17880 set: function(shouldHighlight) {
17881 if (!this.$gutterLineHighlight) {
17882 this.$gutterLineHighlight = dom.createElement("div");
17883 this.$gutterLineHighlight.className = "ace_gutter-active-line";
17884 this.$gutter.appendChild(this.$gutterLineHighlight);
17885 return;
17886 }
17887
17888 this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
17889 if (this.$cursorLayer.$pixelPos)
17890 this.$updateGutterLineHighlight();
17891 },
17892 initialValue: false,
17893 value: true
17894 },
17895 hScrollBarAlwaysVisible: {
17896 set: function(val) {
17897 if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)
17898 this.$loop.schedule(this.CHANGE_SCROLL);
17899 },
17900 initialValue: false
17901 },
17902 vScrollBarAlwaysVisible: {
17903 set: function(val) {
17904 if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)
17905 this.$loop.schedule(this.CHANGE_SCROLL);
17906 },
17907 initialValue: false
17908 },
17909 fontSize: {
17910 set: function(size) {
17911 if (typeof size == "number")
17912 size = size + "px";
17913 this.container.style.fontSize = size;
17914 this.updateFontSize();
17915 },
17916 initialValue: 12
17917 },
17918 fontFamily: {
17919 set: function(name) {
17920 this.container.style.fontFamily = name;
17921 this.updateFontSize();
17922 }
17923 },
17924 maxLines: {
17925 set: function(val) {
17926 this.updateFull();
17927 }
17928 },
17929 minLines: {
17930 set: function(val) {
17931 this.updateFull();
17932 }
17933 },
17934 maxPixelHeight: {
17935 set: function(val) {
17936 this.updateFull();
17937 },
17938 initialValue: 0
17939 },
17940 scrollPastEnd: {
17941 set: function(val) {
17942 val = +val || 0;
17943 if (this.$scrollPastEnd == val)
17944 return;
17945 this.$scrollPastEnd = val;
17946 this.$loop.schedule(this.CHANGE_SCROLL);
17947 },
17948 initialValue: 0,
17949 handlesSet: true
17950 },
17951 fixedWidthGutter: {
17952 set: function(val) {
17953 this.$gutterLayer.$fixedWidth = !!val;
17954 this.$loop.schedule(this.CHANGE_GUTTER);
17955 }
17956 },
17957 theme: {
17958 set: function(val) { this.setTheme(val); },
17959 get: function() { return this.$themeId || this.theme; },
17960 initialValue: "./theme/textmate",
17961 handlesSet: true
17962 }
17963 });
17964
17965 exports.VirtualRenderer = VirtualRenderer;
17966 });
17967
17968 define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"], function(require, exports, module) {
17969 "use strict";
17970
17971 var oop = require("../lib/oop");
17972 var net = require("../lib/net");
17973 var EventEmitter = require("../lib/event_emitter").EventEmitter;
17974 var config = require("../config");
17975
17976 function $workerBlob(workerUrl) {
17977 var script = "importScripts('" + net.qualifyURL(workerUrl) + "');";
17978 try {
17979 return new Blob([script], {"type": "application/javascript"});
17980 } catch (e) { // Backwards-compatibility
17981 var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
17982 var blobBuilder = new BlobBuilder();
17983 blobBuilder.append(script);
17984 return blobBuilder.getBlob("application/javascript");
17985 }
17986 }
17987
17988 function createWorker(workerUrl) {
17989 var blob = $workerBlob(workerUrl);
17990 var URL = window.URL || window.webkitURL;
17991 var blobURL = URL.createObjectURL(blob);
17992 return new Worker(blobURL);
17993 }
17994
17995 var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl, importScripts) {
17996 this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
17997 this.changeListener = this.changeListener.bind(this);
17998 this.onMessage = this.onMessage.bind(this);
17999 if (require.nameToUrl && !require.toUrl)
18000 require.toUrl = require.nameToUrl;
18001
18002 if (config.get("packaged") || !require.toUrl) {
18003 workerUrl = workerUrl || config.moduleUrl(mod, "worker");
18004 } else {
18005 var normalizePath = this.$normalizePath;
18006 workerUrl = workerUrl || normalizePath(require.toUrl("ace/worker/worker.js", null, "_"));
18007
18008 var tlns = {};
18009 topLevelNamespaces.forEach(function(ns) {
18010 tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, ""));
18011 });
18012 }
18013
18014 this.$worker = createWorker(workerUrl);
18015 if (importScripts) {
18016 this.send("importScripts", importScripts);
18017 }
18018 this.$worker.postMessage({
18019 init : true,
18020 tlns : tlns,
18021 module : mod,
18022 classname : classname
18023 });
18024
18025 this.callbackId = 1;
18026 this.callbacks = {};
18027
18028 this.$worker.onmessage = this.onMessage;
18029 };
18030
18031 (function(){
18032
18033 oop.implement(this, EventEmitter);
18034
18035 this.onMessage = function(e) {
18036 var msg = e.data;
18037 switch (msg.type) {
18038 case "event":
18039 this._signal(msg.name, {data: msg.data});
18040 break;
18041 case "call":
18042 var callback = this.callbacks[msg.id];
18043 if (callback) {
18044 callback(msg.data);
18045 delete this.callbacks[msg.id];
18046 }
18047 break;
18048 case "error":
18049 this.reportError(msg.data);
18050 break;
18051 case "log":
18052 window.console && console.log && console.log.apply(console, msg.data);
18053 break;
18054 }
18055 };
18056
18057 this.reportError = function(err) {
18058 window.console && console.error && console.error(err);
18059 };
18060
18061 this.$normalizePath = function(path) {
18062 return net.qualifyURL(path);
18063 };
18064
18065 this.terminate = function() {
18066 this._signal("terminate", {});
18067 this.deltaQueue = null;
18068 this.$worker.terminate();
18069 this.$worker = null;
18070 if (this.$doc)
18071 this.$doc.off("change", this.changeListener);
18072 this.$doc = null;
18073 };
18074
18075 this.send = function(cmd, args) {
18076 this.$worker.postMessage({command: cmd, args: args});
18077 };
18078
18079 this.call = function(cmd, args, callback) {
18080 if (callback) {
18081 var id = this.callbackId++;
18082 this.callbacks[id] = callback;
18083 args.push(id);
18084 }
18085 this.send(cmd, args);
18086 };
18087
18088 this.emit = function(event, data) {
18089 try {
18090 this.$worker.postMessage({event: event, data: {data: data.data}});
18091 }
18092 catch(ex) {
18093 console.error(ex.stack);
18094 }
18095 };
18096
18097 this.attachToDocument = function(doc) {
18098 if (this.$doc)
18099 this.terminate();
18100
18101 this.$doc = doc;
18102 this.call("setValue", [doc.getValue()]);
18103 doc.on("change", this.changeListener);
18104 };
18105
18106 this.changeListener = function(delta) {
18107 if (!this.deltaQueue) {
18108 this.deltaQueue = [];
18109 setTimeout(this.$sendDeltaQueue, 0);
18110 }
18111 if (delta.action == "insert")
18112 this.deltaQueue.push(delta.start, delta.lines);
18113 else
18114 this.deltaQueue.push(delta.start, delta.end);
18115 };
18116
18117 this.$sendDeltaQueue = function() {
18118 var q = this.deltaQueue;
18119 if (!q) return;
18120 this.deltaQueue = null;
18121 if (q.length > 50 && q.length > this.$doc.getLength() >> 1) {
18122 this.call("setValue", [this.$doc.getValue()]);
18123 } else
18124 this.emit("change", {data: q});
18125 };
18126
18127 }).call(WorkerClient.prototype);
18128
18129
18130 var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
18131 this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
18132 this.changeListener = this.changeListener.bind(this);
18133 this.callbackId = 1;
18134 this.callbacks = {};
18135 this.messageBuffer = [];
18136
18137 var main = null;
18138 var emitSync = false;
18139 var sender = Object.create(EventEmitter);
18140 var _self = this;
18141
18142 this.$worker = {};
18143 this.$worker.terminate = function() {};
18144 this.$worker.postMessage = function(e) {
18145 _self.messageBuffer.push(e);
18146 if (main) {
18147 if (emitSync)
18148 setTimeout(processNext);
18149 else
18150 processNext();
18151 }
18152 };
18153 this.setEmitSync = function(val) { emitSync = val; };
18154
18155 var processNext = function() {
18156 var msg = _self.messageBuffer.shift();
18157 if (msg.command)
18158 main[msg.command].apply(main, msg.args);
18159 else if (msg.event)
18160 sender._signal(msg.event, msg.data);
18161 };
18162
18163 sender.postMessage = function(msg) {
18164 _self.onMessage({data: msg});
18165 };
18166 sender.callback = function(data, callbackId) {
18167 this.postMessage({type: "call", id: callbackId, data: data});
18168 };
18169 sender.emit = function(name, data) {
18170 this.postMessage({type: "event", name: name, data: data});
18171 };
18172
18173 config.loadModule(["worker", mod], function(Main) {
18174 main = new Main[classname](sender);
18175 while (_self.messageBuffer.length)
18176 processNext();
18177 });
18178 };
18179
18180 UIWorkerClient.prototype = WorkerClient.prototype;
18181
18182 exports.UIWorkerClient = UIWorkerClient;
18183 exports.WorkerClient = WorkerClient;
18184 exports.createWorker = createWorker;
18185
18186
18187 });
18188
18189 define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"], function(require, exports, module) {
18190 "use strict";
18191
18192 var Range = require("./range").Range;
18193 var EventEmitter = require("./lib/event_emitter").EventEmitter;
18194 var oop = require("./lib/oop");
18195
18196 var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
18197 var _self = this;
18198 this.length = length;
18199 this.session = session;
18200 this.doc = session.getDocument();
18201 this.mainClass = mainClass;
18202 this.othersClass = othersClass;
18203 this.$onUpdate = this.onUpdate.bind(this);
18204 this.doc.on("change", this.$onUpdate);
18205 this.$others = others;
18206
18207 this.$onCursorChange = function() {
18208 setTimeout(function() {
18209 _self.onCursorChange();
18210 });
18211 };
18212
18213 this.$pos = pos;
18214 var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
18215 this.$undoStackDepth = undoStack.length;
18216 this.setup();
18217
18218 session.selection.on("changeCursor", this.$onCursorChange);
18219 };
18220
18221 (function() {
18222
18223 oop.implement(this, EventEmitter);
18224 this.setup = function() {
18225 var _self = this;
18226 var doc = this.doc;
18227 var session = this.session;
18228
18229 this.selectionBefore = session.selection.toJSON();
18230 if (session.selection.inMultiSelectMode)
18231 session.selection.toSingleRange();
18232
18233 this.pos = doc.createAnchor(this.$pos.row, this.$pos.column);
18234 var pos = this.pos;
18235 pos.$insertRight = true;
18236 pos.detach();
18237 pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
18238 this.others = [];
18239 this.$others.forEach(function(other) {
18240 var anchor = doc.createAnchor(other.row, other.column);
18241 anchor.$insertRight = true;
18242 anchor.detach();
18243 _self.others.push(anchor);
18244 });
18245 session.setUndoSelect(false);
18246 };
18247 this.showOtherMarkers = function() {
18248 if (this.othersActive) return;
18249 var session = this.session;
18250 var _self = this;
18251 this.othersActive = true;
18252 this.others.forEach(function(anchor) {
18253 anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
18254 });
18255 };
18256 this.hideOtherMarkers = function() {
18257 if (!this.othersActive) return;
18258 this.othersActive = false;
18259 for (var i = 0; i < this.others.length; i++) {
18260 this.session.removeMarker(this.others[i].markerId);
18261 }
18262 };
18263 this.onUpdate = function(delta) {
18264 if (this.$updating)
18265 return this.updateAnchors(delta);
18266
18267 var range = delta;
18268 if (range.start.row !== range.end.row) return;
18269 if (range.start.row !== this.pos.row) return;
18270 this.$updating = true;
18271 var lengthDiff = delta.action === "insert" ? range.end.column - range.start.column : range.start.column - range.end.column;
18272 var inMainRange = range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1;
18273 var distanceFromStart = range.start.column - this.pos.column;
18274
18275 this.updateAnchors(delta);
18276
18277 if (inMainRange)
18278 this.length += lengthDiff;
18279
18280 if (inMainRange && !this.session.$fromUndo) {
18281 if (delta.action === 'insert') {
18282 for (var i = this.others.length - 1; i >= 0; i--) {
18283 var otherPos = this.others[i];
18284 var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
18285 this.doc.insertMergedLines(newPos, delta.lines);
18286 }
18287 } else if (delta.action === 'remove') {
18288 for (var i = this.others.length - 1; i >= 0; i--) {
18289 var otherPos = this.others[i];
18290 var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
18291 this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
18292 }
18293 }
18294 }
18295
18296 this.$updating = false;
18297 this.updateMarkers();
18298 };
18299
18300 this.updateAnchors = function(delta) {
18301 this.pos.onChange(delta);
18302 for (var i = this.others.length; i--;)
18303 this.others[i].onChange(delta);
18304 this.updateMarkers();
18305 };
18306
18307 this.updateMarkers = function() {
18308 if (this.$updating)
18309 return;
18310 var _self = this;
18311 var session = this.session;
18312 var updateMarker = function(pos, className) {
18313 session.removeMarker(pos.markerId);
18314 pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column+_self.length), className, null, false);
18315 };
18316 updateMarker(this.pos, this.mainClass);
18317 for (var i = this.others.length; i--;)
18318 updateMarker(this.others[i], this.othersClass);
18319 };
18320
18321 this.onCursorChange = function(event) {
18322 if (this.$updating || !this.session) return;
18323 var pos = this.session.selection.getCursor();
18324 if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
18325 this.showOtherMarkers();
18326 this._emit("cursorEnter", event);
18327 } else {
18328 this.hideOtherMarkers();
18329 this._emit("cursorLeave", event);
18330 }
18331 };
18332 this.detach = function() {
18333 this.session.removeMarker(this.pos && this.pos.markerId);
18334 this.hideOtherMarkers();
18335 this.doc.removeEventListener("change", this.$onUpdate);
18336 this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
18337 this.session.setUndoSelect(true);
18338 this.session = null;
18339 };
18340 this.cancel = function() {
18341 if (this.$undoStackDepth === -1)
18342 return;
18343 var undoManager = this.session.getUndoManager();
18344 var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
18345 for (var i = 0; i < undosRequired; i++) {
18346 undoManager.undo(true);
18347 }
18348 if (this.selectionBefore)
18349 this.session.selection.fromJSON(this.selectionBefore);
18350 };
18351 }).call(PlaceHolder.prototype);
18352
18353
18354 exports.PlaceHolder = PlaceHolder;
18355 });
18356
18357 define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
18358
18359 var event = require("../lib/event");
18360 var useragent = require("../lib/useragent");
18361 function isSamePoint(p1, p2) {
18362 return p1.row == p2.row && p1.column == p2.column;
18363 }
18364
18365 function onMouseDown(e) {
18366 var ev = e.domEvent;
18367 var alt = ev.altKey;
18368 var shift = ev.shiftKey;
18369 var ctrl = ev.ctrlKey;
18370 var accel = e.getAccelKey();
18371 var button = e.getButton();
18372
18373 if (ctrl && useragent.isMac)
18374 button = ev.button;
18375
18376 if (e.editor.inMultiSelectMode && button == 2) {
18377 e.editor.textInput.onContextMenu(e.domEvent);
18378 return;
18379 }
18380
18381 if (!ctrl && !alt && !accel) {
18382 if (button === 0 && e.editor.inMultiSelectMode)
18383 e.editor.exitMultiSelectMode();
18384 return;
18385 }
18386
18387 if (button !== 0)
18388 return;
18389
18390 var editor = e.editor;
18391 var selection = editor.selection;
18392 var isMultiSelect = editor.inMultiSelectMode;
18393 var pos = e.getDocumentPosition();
18394 var cursor = selection.getCursor();
18395 var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
18396
18397 var mouseX = e.x, mouseY = e.y;
18398 var onMouseSelection = function(e) {
18399 mouseX = e.clientX;
18400 mouseY = e.clientY;
18401 };
18402
18403 var session = editor.session;
18404 var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
18405 var screenCursor = screenAnchor;
18406
18407 var selectionMode;
18408 if (editor.$mouseHandler.$enableJumpToDef) {
18409 if (ctrl && alt || accel && alt)
18410 selectionMode = shift ? "block" : "add";
18411 else if (alt && editor.$blockSelectEnabled)
18412 selectionMode = "block";
18413 } else {
18414 if (accel && !alt) {
18415 selectionMode = "add";
18416 if (!isMultiSelect && shift)
18417 return;
18418 } else if (alt && editor.$blockSelectEnabled) {
18419 selectionMode = "block";
18420 }
18421 }
18422
18423 if (selectionMode && useragent.isMac && ev.ctrlKey) {
18424 editor.$mouseHandler.cancelContextMenu();
18425 }
18426
18427 if (selectionMode == "add") {
18428 if (!isMultiSelect && inSelection)
18429 return; // dragging
18430
18431 if (!isMultiSelect) {
18432 var range = selection.toOrientedRange();
18433 editor.addSelectionMarker(range);
18434 }
18435
18436 var oldRange = selection.rangeList.rangeAtPoint(pos);
18437
18438
18439 editor.$blockScrolling++;
18440 editor.inVirtualSelectionMode = true;
18441
18442 if (shift) {
18443 oldRange = null;
18444 range = selection.ranges[0] || range;
18445 editor.removeSelectionMarker(range);
18446 }
18447 editor.once("mouseup", function() {
18448 var tmpSel = selection.toOrientedRange();
18449
18450 if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
18451 selection.substractPoint(tmpSel.cursor);
18452 else {
18453 if (shift) {
18454 selection.substractPoint(range.cursor);
18455 } else if (range) {
18456 editor.removeSelectionMarker(range);
18457 selection.addRange(range);
18458 }
18459 selection.addRange(tmpSel);
18460 }
18461 editor.$blockScrolling--;
18462 editor.inVirtualSelectionMode = false;
18463 });
18464
18465 } else if (selectionMode == "block") {
18466 e.stop();
18467 editor.inVirtualSelectionMode = true;
18468 var initialRange;
18469 var rectSel = [];
18470 var blockSelect = function() {
18471 var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
18472 var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX);
18473
18474 if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))
18475 return;
18476 screenCursor = newCursor;
18477
18478 editor.$blockScrolling++;
18479 editor.selection.moveToPosition(cursor);
18480 editor.renderer.scrollCursorIntoView();
18481
18482 editor.removeSelectionMarkers(rectSel);
18483 rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
18484 if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())
18485 rectSel[0] = editor.$mouseHandler.$clickSelection.clone();
18486 rectSel.forEach(editor.addSelectionMarker, editor);
18487 editor.updateSelectionMarkers();
18488 editor.$blockScrolling--;
18489 };
18490 editor.$blockScrolling++;
18491 if (isMultiSelect && !accel) {
18492 selection.toSingleRange();
18493 } else if (!isMultiSelect && accel) {
18494 initialRange = selection.toOrientedRange();
18495 editor.addSelectionMarker(initialRange);
18496 }
18497
18498 if (shift)
18499 screenAnchor = session.documentToScreenPosition(selection.lead);
18500 else
18501 selection.moveToPosition(pos);
18502 editor.$blockScrolling--;
18503
18504 screenCursor = {row: -1, column: -1};
18505
18506 var onMouseSelectionEnd = function(e) {
18507 clearInterval(timerId);
18508 editor.removeSelectionMarkers(rectSel);
18509 if (!rectSel.length)
18510 rectSel = [selection.toOrientedRange()];
18511 editor.$blockScrolling++;
18512 if (initialRange) {
18513 editor.removeSelectionMarker(initialRange);
18514 selection.toSingleRange(initialRange);
18515 }
18516 for (var i = 0; i < rectSel.length; i++)
18517 selection.addRange(rectSel[i]);
18518 editor.inVirtualSelectionMode = false;
18519 editor.$mouseHandler.$clickSelection = null;
18520 editor.$blockScrolling--;
18521 };
18522
18523 var onSelectionInterval = blockSelect;
18524
18525 event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
18526 var timerId = setInterval(function() {onSelectionInterval();}, 20);
18527
18528 return e.preventDefault();
18529 }
18530 }
18531
18532
18533 exports.onMouseDown = onMouseDown;
18534
18535 });
18536
18537 define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"], function(require, exports, module) {
18538 exports.defaultCommands = [{
18539 name: "addCursorAbove",
18540 exec: function(editor) { editor.selectMoreLines(-1); },
18541 bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
18542 scrollIntoView: "cursor",
18543 readOnly: true
18544 }, {
18545 name: "addCursorBelow",
18546 exec: function(editor) { editor.selectMoreLines(1); },
18547 bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
18548 scrollIntoView: "cursor",
18549 readOnly: true
18550 }, {
18551 name: "addCursorAboveSkipCurrent",
18552 exec: function(editor) { editor.selectMoreLines(-1, true); },
18553 bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
18554 scrollIntoView: "cursor",
18555 readOnly: true
18556 }, {
18557 name: "addCursorBelowSkipCurrent",
18558 exec: function(editor) { editor.selectMoreLines(1, true); },
18559 bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
18560 scrollIntoView: "cursor",
18561 readOnly: true
18562 }, {
18563 name: "selectMoreBefore",
18564 exec: function(editor) { editor.selectMore(-1); },
18565 bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
18566 scrollIntoView: "cursor",
18567 readOnly: true
18568 }, {
18569 name: "selectMoreAfter",
18570 exec: function(editor) { editor.selectMore(1); },
18571 bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
18572 scrollIntoView: "cursor",
18573 readOnly: true
18574 }, {
18575 name: "selectNextBefore",
18576 exec: function(editor) { editor.selectMore(-1, true); },
18577 bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
18578 scrollIntoView: "cursor",
18579 readOnly: true
18580 }, {
18581 name: "selectNextAfter",
18582 exec: function(editor) { editor.selectMore(1, true); },
18583 bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
18584 scrollIntoView: "cursor",
18585 readOnly: true
18586 }, {
18587 name: "splitIntoLines",
18588 exec: function(editor) { editor.multiSelect.splitIntoLines(); },
18589 bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
18590 readOnly: true
18591 }, {
18592 name: "alignCursors",
18593 exec: function(editor) { editor.alignCursors(); },
18594 bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"},
18595 scrollIntoView: "cursor"
18596 }, {
18597 name: "findAll",
18598 exec: function(editor) { editor.findAll(); },
18599 bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"},
18600 scrollIntoView: "cursor",
18601 readOnly: true
18602 }];
18603 exports.multiSelectCommands = [{
18604 name: "singleSelection",
18605 bindKey: "esc",
18606 exec: function(editor) { editor.exitMultiSelectMode(); },
18607 scrollIntoView: "cursor",
18608 readOnly: true,
18609 isAvailable: function(editor) {return editor && editor.inMultiSelectMode;}
18610 }];
18611
18612 var HashHandler = require("../keyboard/hash_handler").HashHandler;
18613 exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
18614
18615 });
18616
18617 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(require, exports, module) {
18618
18619 var RangeList = require("./range_list").RangeList;
18620 var Range = require("./range").Range;
18621 var Selection = require("./selection").Selection;
18622 var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
18623 var event = require("./lib/event");
18624 var lang = require("./lib/lang");
18625 var commands = require("./commands/multi_select_commands");
18626 exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
18627 var Search = require("./search").Search;
18628 var search = new Search();
18629
18630 function find(session, needle, dir) {
18631 search.$options.wrap = true;
18632 search.$options.needle = needle;
18633 search.$options.backwards = dir == -1;
18634 return search.find(session);
18635 }
18636 var EditSession = require("./edit_session").EditSession;
18637 (function() {
18638 this.getSelectionMarkers = function() {
18639 return this.$selectionMarkers;
18640 };
18641 }).call(EditSession.prototype);
18642 (function() {
18643 this.ranges = null;
18644 this.rangeList = null;
18645 this.addRange = function(range, $blockChangeEvents) {
18646 if (!range)
18647 return;
18648
18649 if (!this.inMultiSelectMode && this.rangeCount === 0) {
18650 var oldRange = this.toOrientedRange();
18651 this.rangeList.add(oldRange);
18652 this.rangeList.add(range);
18653 if (this.rangeList.ranges.length != 2) {
18654 this.rangeList.removeAll();
18655 return $blockChangeEvents || this.fromOrientedRange(range);
18656 }
18657 this.rangeList.removeAll();
18658 this.rangeList.add(oldRange);
18659 this.$onAddRange(oldRange);
18660 }
18661
18662 if (!range.cursor)
18663 range.cursor = range.end;
18664
18665 var removed = this.rangeList.add(range);
18666
18667 this.$onAddRange(range);
18668
18669 if (removed.length)
18670 this.$onRemoveRange(removed);
18671
18672 if (this.rangeCount > 1 && !this.inMultiSelectMode) {
18673 this._signal("multiSelect");
18674 this.inMultiSelectMode = true;
18675 this.session.$undoSelect = false;
18676 this.rangeList.attach(this.session);
18677 }
18678
18679 return $blockChangeEvents || this.fromOrientedRange(range);
18680 };
18681
18682 this.toSingleRange = function(range) {
18683 range = range || this.ranges[0];
18684 var removed = this.rangeList.removeAll();
18685 if (removed.length)
18686 this.$onRemoveRange(removed);
18687
18688 range && this.fromOrientedRange(range);
18689 };
18690 this.substractPoint = function(pos) {
18691 var removed = this.rangeList.substractPoint(pos);
18692 if (removed) {
18693 this.$onRemoveRange(removed);
18694 return removed[0];
18695 }
18696 };
18697 this.mergeOverlappingRanges = function() {
18698 var removed = this.rangeList.merge();
18699 if (removed.length)
18700 this.$onRemoveRange(removed);
18701 else if(this.ranges[0])
18702 this.fromOrientedRange(this.ranges[0]);
18703 };
18704
18705 this.$onAddRange = function(range) {
18706 this.rangeCount = this.rangeList.ranges.length;
18707 this.ranges.unshift(range);
18708 this._signal("addRange", {range: range});
18709 };
18710
18711 this.$onRemoveRange = function(removed) {
18712 this.rangeCount = this.rangeList.ranges.length;
18713 if (this.rangeCount == 1 && this.inMultiSelectMode) {
18714 var lastRange = this.rangeList.ranges.pop();
18715 removed.push(lastRange);
18716 this.rangeCount = 0;
18717 }
18718
18719 for (var i = removed.length; i--; ) {
18720 var index = this.ranges.indexOf(removed[i]);
18721 this.ranges.splice(index, 1);
18722 }
18723
18724 this._signal("removeRange", {ranges: removed});
18725
18726 if (this.rangeCount === 0 && this.inMultiSelectMode) {
18727 this.inMultiSelectMode = false;
18728 this._signal("singleSelect");
18729 this.session.$undoSelect = true;
18730 this.rangeList.detach(this.session);
18731 }
18732
18733 lastRange = lastRange || this.ranges[0];
18734 if (lastRange && !lastRange.isEqual(this.getRange()))
18735 this.fromOrientedRange(lastRange);
18736 };
18737 this.$initRangeList = function() {
18738 if (this.rangeList)
18739 return;
18740
18741 this.rangeList = new RangeList();
18742 this.ranges = [];
18743 this.rangeCount = 0;
18744 };
18745 this.getAllRanges = function() {
18746 return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];
18747 };
18748
18749 this.splitIntoLines = function () {
18750 if (this.rangeCount > 1) {
18751 var ranges = this.rangeList.ranges;
18752 var lastRange = ranges[ranges.length - 1];
18753 var range = Range.fromPoints(ranges[0].start, lastRange.end);
18754
18755 this.toSingleRange();
18756 this.setSelectionRange(range, lastRange.cursor == lastRange.start);
18757 } else {
18758 var range = this.getRange();
18759 var isBackwards = this.isBackwards();
18760 var startRow = range.start.row;
18761 var endRow = range.end.row;
18762 if (startRow == endRow) {
18763 if (isBackwards)
18764 var start = range.end, end = range.start;
18765 else
18766 var start = range.start, end = range.end;
18767
18768 this.addRange(Range.fromPoints(end, end));
18769 this.addRange(Range.fromPoints(start, start));
18770 return;
18771 }
18772
18773 var rectSel = [];
18774 var r = this.getLineRange(startRow, true);
18775 r.start.column = range.start.column;
18776 rectSel.push(r);
18777
18778 for (var i = startRow + 1; i < endRow; i++)
18779 rectSel.push(this.getLineRange(i, true));
18780
18781 r = this.getLineRange(endRow, true);
18782 r.end.column = range.end.column;
18783 rectSel.push(r);
18784
18785 rectSel.forEach(this.addRange, this);
18786 }
18787 };
18788 this.toggleBlockSelection = function () {
18789 if (this.rangeCount > 1) {
18790 var ranges = this.rangeList.ranges;
18791 var lastRange = ranges[ranges.length - 1];
18792 var range = Range.fromPoints(ranges[0].start, lastRange.end);
18793
18794 this.toSingleRange();
18795 this.setSelectionRange(range, lastRange.cursor == lastRange.start);
18796 } else {
18797 var cursor = this.session.documentToScreenPosition(this.selectionLead);
18798 var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
18799
18800 var rectSel = this.rectangularRangeBlock(cursor, anchor);
18801 rectSel.forEach(this.addRange, this);
18802 }
18803 };
18804 this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
18805 var rectSel = [];
18806
18807 var xBackwards = screenCursor.column < screenAnchor.column;
18808 if (xBackwards) {
18809 var startColumn = screenCursor.column;
18810 var endColumn = screenAnchor.column;
18811 var startOffsetX = screenCursor.offsetX;
18812 var endOffsetX = screenAnchor.offsetX;
18813 } else {
18814 var startColumn = screenAnchor.column;
18815 var endColumn = screenCursor.column;
18816 var startOffsetX = screenAnchor.offsetX;
18817 var endOffsetX = screenCursor.offsetX;
18818 }
18819
18820 var yBackwards = screenCursor.row < screenAnchor.row;
18821 if (yBackwards) {
18822 var startRow = screenCursor.row;
18823 var endRow = screenAnchor.row;
18824 } else {
18825 var startRow = screenAnchor.row;
18826 var endRow = screenCursor.row;
18827 }
18828
18829 if (startColumn < 0)
18830 startColumn = 0;
18831 if (startRow < 0)
18832 startRow = 0;
18833
18834 if (startRow == endRow)
18835 includeEmptyLines = true;
18836
18837 for (var row = startRow; row <= endRow; row++) {
18838 var range = Range.fromPoints(
18839 this.session.screenToDocumentPosition(row, startColumn, startOffsetX),
18840 this.session.screenToDocumentPosition(row, endColumn, endOffsetX)
18841 );
18842 if (range.isEmpty()) {
18843 if (docEnd && isSamePoint(range.end, docEnd))
18844 break;
18845 var docEnd = range.end;
18846 }
18847 range.cursor = xBackwards ? range.start : range.end;
18848 rectSel.push(range);
18849 }
18850
18851 if (yBackwards)
18852 rectSel.reverse();
18853
18854 if (!includeEmptyLines) {
18855 var end = rectSel.length - 1;
18856 while (rectSel[end].isEmpty() && end > 0)
18857 end--;
18858 if (end > 0) {
18859 var start = 0;
18860 while (rectSel[start].isEmpty())
18861 start++;
18862 }
18863 for (var i = end; i >= start; i--) {
18864 if (rectSel[i].isEmpty())
18865 rectSel.splice(i, 1);
18866 }
18867 }
18868
18869 return rectSel;
18870 };
18871 }).call(Selection.prototype);
18872 var Editor = require("./editor").Editor;
18873 (function() {
18874 this.updateSelectionMarkers = function() {
18875 this.renderer.updateCursor();
18876 this.renderer.updateBackMarkers();
18877 };
18878 this.addSelectionMarker = function(orientedRange) {
18879 if (!orientedRange.cursor)
18880 orientedRange.cursor = orientedRange.end;
18881
18882 var style = this.getSelectionStyle();
18883 orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
18884
18885 this.session.$selectionMarkers.push(orientedRange);
18886 this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
18887 return orientedRange;
18888 };
18889 this.removeSelectionMarker = function(range) {
18890 if (!range.marker)
18891 return;
18892 this.session.removeMarker(range.marker);
18893 var index = this.session.$selectionMarkers.indexOf(range);
18894 if (index != -1)
18895 this.session.$selectionMarkers.splice(index, 1);
18896 this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
18897 };
18898
18899 this.removeSelectionMarkers = function(ranges) {
18900 var markerList = this.session.$selectionMarkers;
18901 for (var i = ranges.length; i--; ) {
18902 var range = ranges[i];
18903 if (!range.marker)
18904 continue;
18905 this.session.removeMarker(range.marker);
18906 var index = markerList.indexOf(range);
18907 if (index != -1)
18908 markerList.splice(index, 1);
18909 }
18910 this.session.selectionMarkerCount = markerList.length;
18911 };
18912
18913 this.$onAddRange = function(e) {
18914 this.addSelectionMarker(e.range);
18915 this.renderer.updateCursor();
18916 this.renderer.updateBackMarkers();
18917 };
18918
18919 this.$onRemoveRange = function(e) {
18920 this.removeSelectionMarkers(e.ranges);
18921 this.renderer.updateCursor();
18922 this.renderer.updateBackMarkers();
18923 };
18924
18925 this.$onMultiSelect = function(e) {
18926 if (this.inMultiSelectMode)
18927 return;
18928 this.inMultiSelectMode = true;
18929
18930 this.setStyle("ace_multiselect");
18931 this.keyBinding.addKeyboardHandler(commands.keyboardHandler);
18932 this.commands.setDefaultHandler("exec", this.$onMultiSelectExec);
18933
18934 this.renderer.updateCursor();
18935 this.renderer.updateBackMarkers();
18936 };
18937
18938 this.$onSingleSelect = function(e) {
18939 if (this.session.multiSelect.inVirtualMode)
18940 return;
18941 this.inMultiSelectMode = false;
18942
18943 this.unsetStyle("ace_multiselect");
18944 this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);
18945
18946 this.commands.removeDefaultHandler("exec", this.$onMultiSelectExec);
18947 this.renderer.updateCursor();
18948 this.renderer.updateBackMarkers();
18949 this._emit("changeSelection");
18950 };
18951
18952 this.$onMultiSelectExec = function(e) {
18953 var command = e.command;
18954 var editor = e.editor;
18955 if (!editor.multiSelect)
18956 return;
18957 if (!command.multiSelectAction) {
18958 var result = command.exec(editor, e.args || {});
18959 editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
18960 editor.multiSelect.mergeOverlappingRanges();
18961 } else if (command.multiSelectAction == "forEach") {
18962 result = editor.forEachSelection(command, e.args);
18963 } else if (command.multiSelectAction == "forEachLine") {
18964 result = editor.forEachSelection(command, e.args, true);
18965 } else if (command.multiSelectAction == "single") {
18966 editor.exitMultiSelectMode();
18967 result = command.exec(editor, e.args || {});
18968 } else {
18969 result = command.multiSelectAction(editor, e.args || {});
18970 }
18971 return result;
18972 };
18973 this.forEachSelection = function(cmd, args, options) {
18974 if (this.inVirtualSelectionMode)
18975 return;
18976 var keepOrder = options && options.keepOrder;
18977 var $byLines = options == true || options && options.$byLines;
18978 var session = this.session;
18979 var selection = this.selection;
18980 var rangeList = selection.rangeList;
18981 var ranges = (keepOrder ? selection : rangeList).ranges;
18982 var result;
18983
18984 if (!ranges.length)
18985 return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
18986
18987 var reg = selection._eventRegistry;
18988 selection._eventRegistry = {};
18989
18990 var tmpSel = new Selection(session);
18991 this.inVirtualSelectionMode = true;
18992 for (var i = ranges.length; i--;) {
18993 if ($byLines) {
18994 while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row)
18995 i--;
18996 }
18997 tmpSel.fromOrientedRange(ranges[i]);
18998 tmpSel.index = i;
18999 this.selection = session.selection = tmpSel;
19000 var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
19001 if (!result && cmdResult !== undefined)
19002 result = cmdResult;
19003 tmpSel.toOrientedRange(ranges[i]);
19004 }
19005 tmpSel.detach();
19006
19007 this.selection = session.selection = selection;
19008 this.inVirtualSelectionMode = false;
19009 selection._eventRegistry = reg;
19010 selection.mergeOverlappingRanges();
19011
19012 var anim = this.renderer.$scrollAnimation;
19013 this.onCursorChange();
19014 this.onSelectionChange();
19015 if (anim && anim.from == anim.to)
19016 this.renderer.animateScrolling(anim.from);
19017
19018 return result;
19019 };
19020 this.exitMultiSelectMode = function() {
19021 if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
19022 return;
19023 this.multiSelect.toSingleRange();
19024 };
19025
19026 this.getSelectedText = function() {
19027 var text = "";
19028 if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
19029 var ranges = this.multiSelect.rangeList.ranges;
19030 var buf = [];
19031 for (var i = 0; i < ranges.length; i++) {
19032 buf.push(this.session.getTextRange(ranges[i]));
19033 }
19034 var nl = this.session.getDocument().getNewLineCharacter();
19035 text = buf.join(nl);
19036 if (text.length == (buf.length - 1) * nl.length)
19037 text = "";
19038 } else if (!this.selection.isEmpty()) {
19039 text = this.session.getTextRange(this.getSelectionRange());
19040 }
19041 return text;
19042 };
19043
19044 this.$checkMultiselectChange = function(e, anchor) {
19045 if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
19046 var range = this.multiSelect.ranges[0];
19047 if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)
19048 return;
19049 var pos = anchor == this.multiSelect.anchor
19050 ? range.cursor == range.start ? range.end : range.start
19051 : range.cursor;
19052 if (pos.row != anchor.row
19053 || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column)
19054 this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());
19055 }
19056 };
19057 this.findAll = function(needle, options, additive) {
19058 options = options || {};
19059 options.needle = needle || options.needle;
19060 if (options.needle == undefined) {
19061 var range = this.selection.isEmpty()
19062 ? this.selection.getWordRange()
19063 : this.selection.getRange();
19064 options.needle = this.session.getTextRange(range);
19065 }
19066 this.$search.set(options);
19067
19068 var ranges = this.$search.findAll(this.session);
19069 if (!ranges.length)
19070 return 0;
19071
19072 this.$blockScrolling += 1;
19073 var selection = this.multiSelect;
19074
19075 if (!additive)
19076 selection.toSingleRange(ranges[0]);
19077
19078 for (var i = ranges.length; i--; )
19079 selection.addRange(ranges[i], true);
19080 if (range && selection.rangeList.rangeAtPoint(range.start))
19081 selection.addRange(range, true);
19082
19083 this.$blockScrolling -= 1;
19084
19085 return ranges.length;
19086 };
19087 this.selectMoreLines = function(dir, skip) {
19088 var range = this.selection.toOrientedRange();
19089 var isBackwards = range.cursor == range.end;
19090
19091 var screenLead = this.session.documentToScreenPosition(range.cursor);
19092 if (this.selection.$desiredColumn)
19093 screenLead.column = this.selection.$desiredColumn;
19094
19095 var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
19096
19097 if (!range.isEmpty()) {
19098 var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
19099 var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
19100 } else {
19101 var anchor = lead;
19102 }
19103
19104 if (isBackwards) {
19105 var newRange = Range.fromPoints(lead, anchor);
19106 newRange.cursor = newRange.start;
19107 } else {
19108 var newRange = Range.fromPoints(anchor, lead);
19109 newRange.cursor = newRange.end;
19110 }
19111
19112 newRange.desiredColumn = screenLead.column;
19113 if (!this.selection.inMultiSelectMode) {
19114 this.selection.addRange(range);
19115 } else {
19116 if (skip)
19117 var toRemove = range.cursor;
19118 }
19119
19120 this.selection.addRange(newRange);
19121 if (toRemove)
19122 this.selection.substractPoint(toRemove);
19123 };
19124 this.transposeSelections = function(dir) {
19125 var session = this.session;
19126 var sel = session.multiSelect;
19127 var all = sel.ranges;
19128
19129 for (var i = all.length; i--; ) {
19130 var range = all[i];
19131 if (range.isEmpty()) {
19132 var tmp = session.getWordRange(range.start.row, range.start.column);
19133 range.start.row = tmp.start.row;
19134 range.start.column = tmp.start.column;
19135 range.end.row = tmp.end.row;
19136 range.end.column = tmp.end.column;
19137 }
19138 }
19139 sel.mergeOverlappingRanges();
19140
19141 var words = [];
19142 for (var i = all.length; i--; ) {
19143 var range = all[i];
19144 words.unshift(session.getTextRange(range));
19145 }
19146
19147 if (dir < 0)
19148 words.unshift(words.pop());
19149 else
19150 words.push(words.shift());
19151
19152 for (var i = all.length; i--; ) {
19153 var range = all[i];
19154 var tmp = range.clone();
19155 session.replace(range, words[i]);
19156 range.start.row = tmp.start.row;
19157 range.start.column = tmp.start.column;
19158 }
19159 };
19160 this.selectMore = function(dir, skip, stopAtFirst) {
19161 var session = this.session;
19162 var sel = session.multiSelect;
19163
19164 var range = sel.toOrientedRange();
19165 if (range.isEmpty()) {
19166 range = session.getWordRange(range.start.row, range.start.column);
19167 range.cursor = dir == -1 ? range.start : range.end;
19168 this.multiSelect.addRange(range);
19169 if (stopAtFirst)
19170 return;
19171 }
19172 var needle = session.getTextRange(range);
19173
19174 var newRange = find(session, needle, dir);
19175 if (newRange) {
19176 newRange.cursor = dir == -1 ? newRange.start : newRange.end;
19177 this.$blockScrolling += 1;
19178 this.session.unfold(newRange);
19179 this.multiSelect.addRange(newRange);
19180 this.$blockScrolling -= 1;
19181 this.renderer.scrollCursorIntoView(null, 0.5);
19182 }
19183 if (skip)
19184 this.multiSelect.substractPoint(range.cursor);
19185 };
19186 this.alignCursors = function() {
19187 var session = this.session;
19188 var sel = session.multiSelect;
19189 var ranges = sel.ranges;
19190 var row = -1;
19191 var sameRowRanges = ranges.filter(function(r) {
19192 if (r.cursor.row == row)
19193 return true;
19194 row = r.cursor.row;
19195 });
19196
19197 if (!ranges.length || sameRowRanges.length == ranges.length - 1) {
19198 var range = this.selection.getRange();
19199 var fr = range.start.row, lr = range.end.row;
19200 var guessRange = fr == lr;
19201 if (guessRange) {
19202 var max = this.session.getLength();
19203 var line;
19204 do {
19205 line = this.session.getLine(lr);
19206 } while (/[=:]/.test(line) && ++lr < max);
19207 do {
19208 line = this.session.getLine(fr);
19209 } while (/[=:]/.test(line) && --fr > 0);
19210
19211 if (fr < 0) fr = 0;
19212 if (lr >= max) lr = max - 1;
19213 }
19214 var lines = this.session.removeFullLines(fr, lr);
19215 lines = this.$reAlignText(lines, guessRange);
19216 this.session.insert({row: fr, column: 0}, lines.join("\n") + "\n");
19217 if (!guessRange) {
19218 range.start.column = 0;
19219 range.end.column = lines[lines.length - 1].length;
19220 }
19221 this.selection.setRange(range);
19222 } else {
19223 sameRowRanges.forEach(function(r) {
19224 sel.substractPoint(r.cursor);
19225 });
19226
19227 var maxCol = 0;
19228 var minSpace = Infinity;
19229 var spaceOffsets = ranges.map(function(r) {
19230 var p = r.cursor;
19231 var line = session.getLine(p.row);
19232 var spaceOffset = line.substr(p.column).search(/\S/g);
19233 if (spaceOffset == -1)
19234 spaceOffset = 0;
19235
19236 if (p.column > maxCol)
19237 maxCol = p.column;
19238 if (spaceOffset < minSpace)
19239 minSpace = spaceOffset;
19240 return spaceOffset;
19241 });
19242 ranges.forEach(function(r, i) {
19243 var p = r.cursor;
19244 var l = maxCol - p.column;
19245 var d = spaceOffsets[i] - minSpace;
19246 if (l > d)
19247 session.insert(p, lang.stringRepeat(" ", l - d));
19248 else
19249 session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
19250
19251 r.start.column = r.end.column = maxCol;
19252 r.start.row = r.end.row = p.row;
19253 r.cursor = r.end;
19254 });
19255 sel.fromOrientedRange(ranges[0]);
19256 this.renderer.updateCursor();
19257 this.renderer.updateBackMarkers();
19258 }
19259 };
19260
19261 this.$reAlignText = function(lines, forceLeft) {
19262 var isLeftAligned = true, isRightAligned = true;
19263 var startW, textW, endW;
19264
19265 return lines.map(function(line) {
19266 var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
19267 if (!m)
19268 return [line];
19269
19270 if (startW == null) {
19271 startW = m[1].length;
19272 textW = m[2].length;
19273 endW = m[3].length;
19274 return m;
19275 }
19276
19277 if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
19278 isRightAligned = false;
19279 if (startW != m[1].length)
19280 isLeftAligned = false;
19281
19282 if (startW > m[1].length)
19283 startW = m[1].length;
19284 if (textW < m[2].length)
19285 textW = m[2].length;
19286 if (endW > m[3].length)
19287 endW = m[3].length;
19288
19289 return m;
19290 }).map(forceLeft ? alignLeft :
19291 isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
19292
19293 function spaces(n) {
19294 return lang.stringRepeat(" ", n);
19295 }
19296
19297 function alignLeft(m) {
19298 return !m[2] ? m[0] : spaces(startW) + m[2]
19299 + spaces(textW - m[2].length + endW)
19300 + m[4].replace(/^([=:])\s+/, "$1 ");
19301 }
19302 function alignRight(m) {
19303 return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
19304 + spaces(endW, " ")
19305 + m[4].replace(/^([=:])\s+/, "$1 ");
19306 }
19307 function unAlign(m) {
19308 return !m[2] ? m[0] : spaces(startW) + m[2]
19309 + spaces(endW)
19310 + m[4].replace(/^([=:])\s+/, "$1 ");
19311 }
19312 };
19313 }).call(Editor.prototype);
19314
19315
19316 function isSamePoint(p1, p2) {
19317 return p1.row == p2.row && p1.column == p2.column;
19318 }
19319 exports.onSessionChange = function(e) {
19320 var session = e.session;
19321 if (session && !session.multiSelect) {
19322 session.$selectionMarkers = [];
19323 session.selection.$initRangeList();
19324 session.multiSelect = session.selection;
19325 }
19326 this.multiSelect = session && session.multiSelect;
19327
19328 var oldSession = e.oldSession;
19329 if (oldSession) {
19330 oldSession.multiSelect.off("addRange", this.$onAddRange);
19331 oldSession.multiSelect.off("removeRange", this.$onRemoveRange);
19332 oldSession.multiSelect.off("multiSelect", this.$onMultiSelect);
19333 oldSession.multiSelect.off("singleSelect", this.$onSingleSelect);
19334 oldSession.multiSelect.lead.off("change", this.$checkMultiselectChange);
19335 oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange);
19336 }
19337
19338 if (session) {
19339 session.multiSelect.on("addRange", this.$onAddRange);
19340 session.multiSelect.on("removeRange", this.$onRemoveRange);
19341 session.multiSelect.on("multiSelect", this.$onMultiSelect);
19342 session.multiSelect.on("singleSelect", this.$onSingleSelect);
19343 session.multiSelect.lead.on("change", this.$checkMultiselectChange);
19344 session.multiSelect.anchor.on("change", this.$checkMultiselectChange);
19345 }
19346
19347 if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {
19348 if (session.selection.inMultiSelectMode)
19349 this.$onMultiSelect();
19350 else
19351 this.$onSingleSelect();
19352 }
19353 };
19354 function MultiSelect(editor) {
19355 if (editor.$multiselectOnSessionChange)
19356 return;
19357 editor.$onAddRange = editor.$onAddRange.bind(editor);
19358 editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
19359 editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
19360 editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
19361 editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);
19362 editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);
19363
19364 editor.$multiselectOnSessionChange(editor);
19365 editor.on("changeSession", editor.$multiselectOnSessionChange);
19366
19367 editor.on("mousedown", onMouseDown);
19368 editor.commands.addCommands(commands.defaultCommands);
19369
19370 addAltCursorListeners(editor);
19371 }
19372
19373 function addAltCursorListeners(editor){
19374 var el = editor.textInput.getElement();
19375 var altCursor = false;
19376 event.addListener(el, "keydown", function(e) {
19377 var altDown = e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey);
19378 if (editor.$blockSelectEnabled && altDown) {
19379 if (!altCursor) {
19380 editor.renderer.setMouseCursor("crosshair");
19381 altCursor = true;
19382 }
19383 } else if (altCursor) {
19384 reset();
19385 }
19386 });
19387
19388 event.addListener(el, "keyup", reset);
19389 event.addListener(el, "blur", reset);
19390 function reset(e) {
19391 if (altCursor) {
19392 editor.renderer.setMouseCursor("");
19393 altCursor = false;
19394 }
19395 }
19396 }
19397
19398 exports.MultiSelect = MultiSelect;
19399
19400
19401 require("./config").defineOptions(Editor.prototype, "editor", {
19402 enableMultiselect: {
19403 set: function(val) {
19404 MultiSelect(this);
19405 if (val) {
19406 this.on("changeSession", this.$multiselectOnSessionChange);
19407 this.on("mousedown", onMouseDown);
19408 } else {
19409 this.off("changeSession", this.$multiselectOnSessionChange);
19410 this.off("mousedown", onMouseDown);
19411 }
19412 },
19413 value: true
19414 },
19415 enableBlockSelect: {
19416 set: function(val) {
19417 this.$blockSelectEnabled = val;
19418 },
19419 value: true
19420 }
19421 });
19422
19423
19424
19425 });
19426
19427 define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"], function(require, exports, module) {
19428 "use strict";
19429
19430 var Range = require("../../range").Range;
19431
19432 var FoldMode = exports.FoldMode = function() {};
19433
19434 (function() {
19435
19436 this.foldingStartMarker = null;
19437 this.foldingStopMarker = null;
19438 this.getFoldWidget = function(session, foldStyle, row) {
19439 var line = session.getLine(row);
19440 if (this.foldingStartMarker.test(line))
19441 return "start";
19442 if (foldStyle == "markbeginend"
19443 && this.foldingStopMarker
19444 && this.foldingStopMarker.test(line))
19445 return "end";
19446 return "";
19447 };
19448
19449 this.getFoldWidgetRange = function(session, foldStyle, row) {
19450 return null;
19451 };
19452
19453 this.indentationBlock = function(session, row, column) {
19454 var re = /\S/;
19455 var line = session.getLine(row);
19456 var startLevel = line.search(re);
19457 if (startLevel == -1)
19458 return;
19459
19460 var startColumn = column || line.length;
19461 var maxRow = session.getLength();
19462 var startRow = row;
19463 var endRow = row;
19464
19465 while (++row < maxRow) {
19466 var level = session.getLine(row).search(re);
19467
19468 if (level == -1)
19469 continue;
19470
19471 if (level <= startLevel)
19472 break;
19473
19474 endRow = row;
19475 }
19476
19477 if (endRow > startRow) {
19478 var endColumn = session.getLine(endRow).length;
19479 return new Range(startRow, startColumn, endRow, endColumn);
19480 }
19481 };
19482
19483 this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
19484 var start = {row: row, column: column + 1};
19485 var end = session.$findClosingBracket(bracket, start, typeRe);
19486 if (!end)
19487 return;
19488
19489 var fw = session.foldWidgets[end.row];
19490 if (fw == null)
19491 fw = session.getFoldWidget(end.row);
19492
19493 if (fw == "start" && end.row > start.row) {
19494 end.row --;
19495 end.column = session.getLine(end.row).length;
19496 }
19497 return Range.fromPoints(start, end);
19498 };
19499
19500 this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
19501 var end = {row: row, column: column};
19502 var start = session.$findOpeningBracket(bracket, end);
19503
19504 if (!start)
19505 return;
19506
19507 start.column++;
19508 end.column--;
19509
19510 return Range.fromPoints(start, end);
19511 };
19512 }).call(FoldMode.prototype);
19513
19514 });
19515
19516 define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
19517 "use strict";
19518
19519 exports.isDark = false;
19520 exports.cssClass = "ace-tm";
19521 exports.cssText = ".ace-tm .ace_gutter {\
19522 background: #f0f0f0;\
19523 color: #333;\
19524 }\
19525 .ace-tm .ace_print-margin {\
19526 width: 1px;\
19527 background: #e8e8e8;\
19528 }\
19529 .ace-tm .ace_fold {\
19530 background-color: #6B72E6;\
19531 }\
19532 .ace-tm {\
19533 background-color: #FFFFFF;\
19534 color: black;\
19535 }\
19536 .ace-tm .ace_cursor {\
19537 color: black;\
19538 }\
19539 .ace-tm .ace_invisible {\
19540 color: rgb(191, 191, 191);\
19541 }\
19542 .ace-tm .ace_storage,\
19543 .ace-tm .ace_keyword {\
19544 color: blue;\
19545 }\
19546 .ace-tm .ace_constant {\
19547 color: rgb(197, 6, 11);\
19548 }\
19549 .ace-tm .ace_constant.ace_buildin {\
19550 color: rgb(88, 72, 246);\
19551 }\
19552 .ace-tm .ace_constant.ace_language {\
19553 color: rgb(88, 92, 246);\
19554 }\
19555 .ace-tm .ace_constant.ace_library {\
19556 color: rgb(6, 150, 14);\
19557 }\
19558 .ace-tm .ace_invalid {\
19559 background-color: rgba(255, 0, 0, 0.1);\
19560 color: red;\
19561 }\
19562 .ace-tm .ace_support.ace_function {\
19563 color: rgb(60, 76, 114);\
19564 }\
19565 .ace-tm .ace_support.ace_constant {\
19566 color: rgb(6, 150, 14);\
19567 }\
19568 .ace-tm .ace_support.ace_type,\
19569 .ace-tm .ace_support.ace_class {\
19570 color: rgb(109, 121, 222);\
19571 }\
19572 .ace-tm .ace_keyword.ace_operator {\
19573 color: rgb(104, 118, 135);\
19574 }\
19575 .ace-tm .ace_string {\
19576 color: rgb(3, 106, 7);\
19577 }\
19578 .ace-tm .ace_comment {\
19579 color: rgb(76, 136, 107);\
19580 }\
19581 .ace-tm .ace_comment.ace_doc {\
19582 color: rgb(0, 102, 255);\
19583 }\
19584 .ace-tm .ace_comment.ace_doc.ace_tag {\
19585 color: rgb(128, 159, 191);\
19586 }\
19587 .ace-tm .ace_constant.ace_numeric {\
19588 color: rgb(0, 0, 205);\
19589 }\
19590 .ace-tm .ace_variable {\
19591 color: rgb(49, 132, 149);\
19592 }\
19593 .ace-tm .ace_xml-pe {\
19594 color: rgb(104, 104, 91);\
19595 }\
19596 .ace-tm .ace_entity.ace_name.ace_function {\
19597 color: #0000A2;\
19598 }\
19599 .ace-tm .ace_heading {\
19600 color: rgb(12, 7, 255);\
19601 }\
19602 .ace-tm .ace_list {\
19603 color:rgb(185, 6, 144);\
19604 }\
19605 .ace-tm .ace_meta.ace_tag {\
19606 color:rgb(0, 22, 142);\
19607 }\
19608 .ace-tm .ace_string.ace_regex {\
19609 color: rgb(255, 0, 0)\
19610 }\
19611 .ace-tm .ace_marker-layer .ace_selection {\
19612 background: rgb(181, 213, 255);\
19613 }\
19614 .ace-tm.ace_multiselect .ace_selection.ace_start {\
19615 box-shadow: 0 0 3px 0px white;\
19616 }\
19617 .ace-tm .ace_marker-layer .ace_step {\
19618 background: rgb(252, 255, 0);\
19619 }\
19620 .ace-tm .ace_marker-layer .ace_stack {\
19621 background: rgb(164, 229, 101);\
19622 }\
19623 .ace-tm .ace_marker-layer .ace_bracket {\
19624 margin: -1px 0 0 -1px;\
19625 border: 1px solid rgb(192, 192, 192);\
19626 }\
19627 .ace-tm .ace_marker-layer .ace_active-line {\
19628 background: rgba(0, 0, 0, 0.07);\
19629 }\
19630 .ace-tm .ace_gutter-active-line {\
19631 background-color : #dcdcdc;\
19632 }\
19633 .ace-tm .ace_marker-layer .ace_selected-word {\
19634 background: rgb(250, 250, 255);\
19635 border: 1px solid rgb(200, 200, 250);\
19636 }\
19637 .ace-tm .ace_indent-guide {\
19638 background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
19639 }\
19640 ";
19641
19642 var dom = require("../lib/dom");
19643 dom.importCssString(exports.cssText, exports.cssClass);
19644 });
19645
19646 define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(require, exports, module) {
19647 "use strict";
19648
19649 var oop = require("./lib/oop");
19650 var dom = require("./lib/dom");
19651 var Range = require("./range").Range;
19652
19653
19654 function LineWidgets(session) {
19655 this.session = session;
19656 this.session.widgetManager = this;
19657 this.session.getRowLength = this.getRowLength;
19658 this.session.$getWidgetScreenLength = this.$getWidgetScreenLength;
19659 this.updateOnChange = this.updateOnChange.bind(this);
19660 this.renderWidgets = this.renderWidgets.bind(this);
19661 this.measureWidgets = this.measureWidgets.bind(this);
19662 this.session._changedWidgets = [];
19663 this.$onChangeEditor = this.$onChangeEditor.bind(this);
19664
19665 this.session.on("change", this.updateOnChange);
19666 this.session.on("changeFold", this.updateOnFold);
19667 this.session.on("changeEditor", this.$onChangeEditor);
19668 }
19669
19670 (function() {
19671 this.getRowLength = function(row) {
19672 var h;
19673 if (this.lineWidgets)
19674 h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
19675 else
19676 h = 0;
19677 if (!this.$useWrapMode || !this.$wrapData[row]) {
19678 return 1 + h;
19679 } else {
19680 return this.$wrapData[row].length + 1 + h;
19681 }
19682 };
19683
19684 this.$getWidgetScreenLength = function() {
19685 var screenRows = 0;
19686 this.lineWidgets.forEach(function(w){
19687 if (w && w.rowCount && !w.hidden)
19688 screenRows += w.rowCount;
19689 });
19690 return screenRows;
19691 };
19692
19693 this.$onChangeEditor = function(e) {
19694 this.attach(e.editor);
19695 };
19696
19697 this.attach = function(editor) {
19698 if (editor && editor.widgetManager && editor.widgetManager != this)
19699 editor.widgetManager.detach();
19700
19701 if (this.editor == editor)
19702 return;
19703
19704 this.detach();
19705 this.editor = editor;
19706
19707 if (editor) {
19708 editor.widgetManager = this;
19709 editor.renderer.on("beforeRender", this.measureWidgets);
19710 editor.renderer.on("afterRender", this.renderWidgets);
19711 }
19712 };
19713 this.detach = function(e) {
19714 var editor = this.editor;
19715 if (!editor)
19716 return;
19717
19718 this.editor = null;
19719 editor.widgetManager = null;
19720
19721 editor.renderer.off("beforeRender", this.measureWidgets);
19722 editor.renderer.off("afterRender", this.renderWidgets);
19723 var lineWidgets = this.session.lineWidgets;
19724 lineWidgets && lineWidgets.forEach(function(w) {
19725 if (w && w.el && w.el.parentNode) {
19726 w._inDocument = false;
19727 w.el.parentNode.removeChild(w.el);
19728 }
19729 });
19730 };
19731
19732 this.updateOnFold = function(e, session) {
19733 var lineWidgets = session.lineWidgets;
19734 if (!lineWidgets || !e.action)
19735 return;
19736 var fold = e.data;
19737 var start = fold.start.row;
19738 var end = fold.end.row;
19739 var hide = e.action == "add";
19740 for (var i = start + 1; i < end; i++) {
19741 if (lineWidgets[i])
19742 lineWidgets[i].hidden = hide;
19743 }
19744 if (lineWidgets[end]) {
19745 if (hide) {
19746 if (!lineWidgets[start])
19747 lineWidgets[start] = lineWidgets[end];
19748 else
19749 lineWidgets[end].hidden = hide;
19750 } else {
19751 if (lineWidgets[start] == lineWidgets[end])
19752 lineWidgets[start] = undefined;
19753 lineWidgets[end].hidden = hide;
19754 }
19755 }
19756 };
19757
19758 this.updateOnChange = function(delta) {
19759 var lineWidgets = this.session.lineWidgets;
19760 if (!lineWidgets) return;
19761
19762 var startRow = delta.start.row;
19763 var len = delta.end.row - startRow;
19764
19765 if (len === 0) {
19766 } else if (delta.action == 'remove') {
19767 var removed = lineWidgets.splice(startRow + 1, len);
19768 removed.forEach(function(w) {
19769 w && this.removeLineWidget(w);
19770 }, this);
19771 this.$updateRows();
19772 } else {
19773 var args = new Array(len);
19774 args.unshift(startRow, 0);
19775 lineWidgets.splice.apply(lineWidgets, args);
19776 this.$updateRows();
19777 }
19778 };
19779
19780 this.$updateRows = function() {
19781 var lineWidgets = this.session.lineWidgets;
19782 if (!lineWidgets) return;
19783 var noWidgets = true;
19784 lineWidgets.forEach(function(w, i) {
19785 if (w) {
19786 noWidgets = false;
19787 w.row = i;
19788 while (w.$oldWidget) {
19789 w.$oldWidget.row = i;
19790 w = w.$oldWidget;
19791 }
19792 }
19793 });
19794 if (noWidgets)
19795 this.session.lineWidgets = null;
19796 };
19797
19798 this.addLineWidget = function(w) {
19799 if (!this.session.lineWidgets)
19800 this.session.lineWidgets = new Array(this.session.getLength());
19801
19802 var old = this.session.lineWidgets[w.row];
19803 if (old) {
19804 w.$oldWidget = old;
19805 if (old.el && old.el.parentNode) {
19806 old.el.parentNode.removeChild(old.el);
19807 old._inDocument = false;
19808 }
19809 }
19810
19811 this.session.lineWidgets[w.row] = w;
19812
19813 w.session = this.session;
19814
19815 var renderer = this.editor.renderer;
19816 if (w.html && !w.el) {
19817 w.el = dom.createElement("div");
19818 w.el.innerHTML = w.html;
19819 }
19820 if (w.el) {
19821 dom.addCssClass(w.el, "ace_lineWidgetContainer");
19822 w.el.style.position = "absolute";
19823 w.el.style.zIndex = 5;
19824 renderer.container.appendChild(w.el);
19825 w._inDocument = true;
19826 }
19827
19828 if (!w.coverGutter) {
19829 w.el.style.zIndex = 3;
19830 }
19831 if (w.pixelHeight == null) {
19832 w.pixelHeight = w.el.offsetHeight;
19833 }
19834 if (w.rowCount == null) {
19835 w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
19836 }
19837
19838 var fold = this.session.getFoldAt(w.row, 0);
19839 w.$fold = fold;
19840 if (fold) {
19841 var lineWidgets = this.session.lineWidgets;
19842 if (w.row == fold.end.row && !lineWidgets[fold.start.row])
19843 lineWidgets[fold.start.row] = w;
19844 else
19845 w.hidden = true;
19846 }
19847
19848 this.session._emit("changeFold", {data:{start:{row: w.row}}});
19849
19850 this.$updateRows();
19851 this.renderWidgets(null, renderer);
19852 this.onWidgetChanged(w);
19853 return w;
19854 };
19855
19856 this.removeLineWidget = function(w) {
19857 w._inDocument = false;
19858 w.session = null;
19859 if (w.el && w.el.parentNode)
19860 w.el.parentNode.removeChild(w.el);
19861 if (w.editor && w.editor.destroy) try {
19862 w.editor.destroy();
19863 } catch(e){}
19864 if (this.session.lineWidgets) {
19865 var w1 = this.session.lineWidgets[w.row];
19866 if (w1 == w) {
19867 this.session.lineWidgets[w.row] = w.$oldWidget;
19868 if (w.$oldWidget)
19869 this.onWidgetChanged(w.$oldWidget);
19870 } else {
19871 while (w1) {
19872 if (w1.$oldWidget == w) {
19873 w1.$oldWidget = w.$oldWidget;
19874 break;
19875 }
19876 w1 = w1.$oldWidget;
19877 }
19878 }
19879 }
19880 this.session._emit("changeFold", {data:{start:{row: w.row}}});
19881 this.$updateRows();
19882 };
19883
19884 this.getWidgetsAtRow = function(row) {
19885 var lineWidgets = this.session.lineWidgets;
19886 var w = lineWidgets && lineWidgets[row];
19887 var list = [];
19888 while (w) {
19889 list.push(w);
19890 w = w.$oldWidget;
19891 }
19892 return list;
19893 };
19894
19895 this.onWidgetChanged = function(w) {
19896 this.session._changedWidgets.push(w);
19897 this.editor && this.editor.renderer.updateFull();
19898 };
19899
19900 this.measureWidgets = function(e, renderer) {
19901 var changedWidgets = this.session._changedWidgets;
19902 var config = renderer.layerConfig;
19903
19904 if (!changedWidgets || !changedWidgets.length) return;
19905 var min = Infinity;
19906 for (var i = 0; i < changedWidgets.length; i++) {
19907 var w = changedWidgets[i];
19908 if (!w || !w.el) continue;
19909 if (w.session != this.session) continue;
19910 if (!w._inDocument) {
19911 if (this.session.lineWidgets[w.row] != w)
19912 continue;
19913 w._inDocument = true;
19914 renderer.container.appendChild(w.el);
19915 }
19916
19917 w.h = w.el.offsetHeight;
19918
19919 if (!w.fixedWidth) {
19920 w.w = w.el.offsetWidth;
19921 w.screenWidth = Math.ceil(w.w / config.characterWidth);
19922 }
19923
19924 var rowCount = w.h / config.lineHeight;
19925 if (w.coverLine) {
19926 rowCount -= this.session.getRowLineCount(w.row);
19927 if (rowCount < 0)
19928 rowCount = 0;
19929 }
19930 if (w.rowCount != rowCount) {
19931 w.rowCount = rowCount;
19932 if (w.row < min)
19933 min = w.row;
19934 }
19935 }
19936 if (min != Infinity) {
19937 this.session._emit("changeFold", {data:{start:{row: min}}});
19938 this.session.lineWidgetWidth = null;
19939 }
19940 this.session._changedWidgets = [];
19941 };
19942
19943 this.renderWidgets = function(e, renderer) {
19944 var config = renderer.layerConfig;
19945 var lineWidgets = this.session.lineWidgets;
19946 if (!lineWidgets)
19947 return;
19948 var first = Math.min(this.firstRow, config.firstRow);
19949 var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);
19950
19951 while (first > 0 && !lineWidgets[first])
19952 first--;
19953
19954 this.firstRow = config.firstRow;
19955 this.lastRow = config.lastRow;
19956
19957 renderer.$cursorLayer.config = config;
19958 for (var i = first; i <= last; i++) {
19959 var w = lineWidgets[i];
19960 if (!w || !w.el) continue;
19961 if (w.hidden) {
19962 w.el.style.top = -100 - (w.pixelHeight || 0) + "px";
19963 continue;
19964 }
19965 if (!w._inDocument) {
19966 w._inDocument = true;
19967 renderer.container.appendChild(w.el);
19968 }
19969 var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top;
19970 if (!w.coverLine)
19971 top += config.lineHeight * this.session.getRowLineCount(w.row);
19972 w.el.style.top = top - config.offset + "px";
19973
19974 var left = w.coverGutter ? 0 : renderer.gutterWidth;
19975 if (!w.fixedWidth)
19976 left -= renderer.scrollLeft;
19977 w.el.style.left = left + "px";
19978
19979 if (w.fullWidth && w.screenWidth) {
19980 w.el.style.minWidth = config.width + 2 * config.padding + "px";
19981 }
19982
19983 if (w.fixedWidth) {
19984 w.el.style.right = renderer.scrollBar.getWidth() + "px";
19985 } else {
19986 w.el.style.right = "";
19987 }
19988 }
19989 };
19990
19991 }).call(LineWidgets.prototype);
19992
19993
19994 exports.LineWidgets = LineWidgets;
19995
19996 });
19997
19998 define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"], function(require, exports, module) {
19999 "use strict";
20000 var LineWidgets = require("../line_widgets").LineWidgets;
20001 var dom = require("../lib/dom");
20002 var Range = require("../range").Range;
20003
20004 function binarySearch(array, needle, comparator) {
20005 var first = 0;
20006 var last = array.length - 1;
20007
20008 while (first <= last) {
20009 var mid = (first + last) >> 1;
20010 var c = comparator(needle, array[mid]);
20011 if (c > 0)
20012 first = mid + 1;
20013 else if (c < 0)
20014 last = mid - 1;
20015 else
20016 return mid;
20017 }
20018 return -(first + 1);
20019 }
20020
20021 function findAnnotations(session, row, dir) {
20022 var annotations = session.getAnnotations().sort(Range.comparePoints);
20023 if (!annotations.length)
20024 return;
20025
20026 var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints);
20027 if (i < 0)
20028 i = -i - 1;
20029
20030 if (i >= annotations.length)
20031 i = dir > 0 ? 0 : annotations.length - 1;
20032 else if (i === 0 && dir < 0)
20033 i = annotations.length - 1;
20034
20035 var annotation = annotations[i];
20036 if (!annotation || !dir)
20037 return;
20038
20039 if (annotation.row === row) {
20040 do {
20041 annotation = annotations[i += dir];
20042 } while (annotation && annotation.row === row);
20043 if (!annotation)
20044 return annotations.slice();
20045 }
20046
20047
20048 var matched = [];
20049 row = annotation.row;
20050 do {
20051 matched[dir < 0 ? "unshift" : "push"](annotation);
20052 annotation = annotations[i += dir];
20053 } while (annotation && annotation.row == row);
20054 return matched.length && matched;
20055 }
20056
20057 exports.showErrorMarker = function(editor, dir) {
20058 var session = editor.session;
20059 if (!session.widgetManager) {
20060 session.widgetManager = new LineWidgets(session);
20061 session.widgetManager.attach(editor);
20062 }
20063
20064 var pos = editor.getCursorPosition();
20065 var row = pos.row;
20066 var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) {
20067 return w.type == "errorMarker";
20068 })[0];
20069 if (oldWidget) {
20070 oldWidget.destroy();
20071 } else {
20072 row -= dir;
20073 }
20074 var annotations = findAnnotations(session, row, dir);
20075 var gutterAnno;
20076 if (annotations) {
20077 var annotation = annotations[0];
20078 pos.column = (annotation.pos && typeof annotation.column != "number"
20079 ? annotation.pos.sc
20080 : annotation.column) || 0;
20081 pos.row = annotation.row;
20082 gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row];
20083 } else if (oldWidget) {
20084 return;
20085 } else {
20086 gutterAnno = {
20087 text: ["Looks good!"],
20088 className: "ace_ok"
20089 };
20090 }
20091 editor.session.unfold(pos.row);
20092 editor.selection.moveToPosition(pos);
20093
20094 var w = {
20095 row: pos.row,
20096 fixedWidth: true,
20097 coverGutter: true,
20098 el: dom.createElement("div"),
20099 type: "errorMarker"
20100 };
20101 var el = w.el.appendChild(dom.createElement("div"));
20102 var arrow = w.el.appendChild(dom.createElement("div"));
20103 arrow.className = "error_widget_arrow " + gutterAnno.className;
20104
20105 var left = editor.renderer.$cursorLayer
20106 .getPixelPosition(pos).left;
20107 arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px";
20108
20109 w.el.className = "error_widget_wrapper";
20110 el.className = "error_widget " + gutterAnno.className;
20111 el.innerHTML = gutterAnno.text.join("<br>");
20112
20113 el.appendChild(dom.createElement("div"));
20114
20115 var kb = function(_, hashId, keyString) {
20116 if (hashId === 0 && (keyString === "esc" || keyString === "return")) {
20117 w.destroy();
20118 return {command: "null"};
20119 }
20120 };
20121
20122 w.destroy = function() {
20123 if (editor.$mouseHandler.isMousePressed)
20124 return;
20125 editor.keyBinding.removeKeyboardHandler(kb);
20126 session.widgetManager.removeLineWidget(w);
20127 editor.off("changeSelection", w.destroy);
20128 editor.off("changeSession", w.destroy);
20129 editor.off("mouseup", w.destroy);
20130 editor.off("change", w.destroy);
20131 };
20132
20133 editor.keyBinding.addKeyboardHandler(kb);
20134 editor.on("changeSelection", w.destroy);
20135 editor.on("changeSession", w.destroy);
20136 editor.on("mouseup", w.destroy);
20137 editor.on("change", w.destroy);
20138
20139 editor.session.widgetManager.addLineWidget(w);
20140
20141 w.el.onmousedown = editor.focus.bind(editor);
20142
20143 editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight});
20144 };
20145
20146
20147 dom.importCssString("\
20148 .error_widget_wrapper {\
20149 background: inherit;\
20150 color: inherit;\
20151 border:none\
20152 }\
20153 .error_widget {\
20154 border-top: solid 2px;\
20155 border-bottom: solid 2px;\
20156 margin: 5px 0;\
20157 padding: 10px 40px;\
20158 white-space: pre-wrap;\
20159 }\
20160 .error_widget.ace_error, .error_widget_arrow.ace_error{\
20161 border-color: #ff5a5a\
20162 }\
20163 .error_widget.ace_warning, .error_widget_arrow.ace_warning{\
20164 border-color: #F1D817\
20165 }\
20166 .error_widget.ace_info, .error_widget_arrow.ace_info{\
20167 border-color: #5a5a5a\
20168 }\
20169 .error_widget.ace_ok, .error_widget_arrow.ace_ok{\
20170 border-color: #5aaa5a\
20171 }\
20172 .error_widget_arrow {\
20173 position: absolute;\
20174 border: solid 5px;\
20175 border-top-color: transparent!important;\
20176 border-right-color: transparent!important;\
20177 border-left-color: transparent!important;\
20178 top: -5px;\
20179 }\
20180 ", "");
20181
20182 });
20183
20184 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(require, exports, module) {
20185 "use strict";
20186
20187 require("./lib/fixoldbrowsers");
20188
20189 var dom = require("./lib/dom");
20190 var event = require("./lib/event");
20191
20192 var Editor = require("./editor").Editor;
20193 var EditSession = require("./edit_session").EditSession;
20194 var UndoManager = require("./undomanager").UndoManager;
20195 var Renderer = require("./virtual_renderer").VirtualRenderer;
20196 require("./worker/worker_client");
20197 require("./keyboard/hash_handler");
20198 require("./placeholder");
20199 require("./multi_select");
20200 require("./mode/folding/fold_mode");
20201 require("./theme/textmate");
20202 require("./ext/error_marker");
20203
20204 exports.config = require("./config");
20205 exports.require = require;
20206
20207 if (typeof define === "function")
20208 exports.define = define;
20209 exports.edit = function(el) {
20210 if (typeof el == "string") {
20211 var _id = el;
20212 el = document.getElementById(_id);
20213 if (!el)
20214 throw new Error("ace.edit can't find div #" + _id);
20215 }
20216
20217 if (el && el.env && el.env.editor instanceof Editor)
20218 return el.env.editor;
20219
20220 var value = "";
20221 if (el && /input|textarea/i.test(el.tagName)) {
20222 var oldNode = el;
20223 value = oldNode.value;
20224 el = dom.createElement("pre");
20225 oldNode.parentNode.replaceChild(el, oldNode);
20226 } else if (el) {
20227 value = dom.getInnerText(el);
20228 el.innerHTML = "";
20229 }
20230
20231 var doc = exports.createEditSession(value);
20232
20233 var editor = new Editor(new Renderer(el));
20234 editor.setSession(doc);
20235
20236 var env = {
20237 document: doc,
20238 editor: editor,
20239 onResize: editor.resize.bind(editor, null)
20240 };
20241 if (oldNode) env.textarea = oldNode;
20242 event.addListener(window, "resize", env.onResize);
20243 editor.on("destroy", function() {
20244 event.removeListener(window, "resize", env.onResize);
20245 env.editor.container.env = null; // prevent memory leak on old ie
20246 });
20247 editor.container.env = editor.env = env;
20248 return editor;
20249 };
20250 exports.createEditSession = function(text, mode) {
20251 var doc = new EditSession(text, mode);
20252 doc.setUndoManager(new UndoManager());
20253 return doc;
20254 };
20255 exports.EditSession = EditSession;
20256 exports.UndoManager = UndoManager;
20257 exports.version = "1.2.9";
20258 });
20259 (function() {
20260 window.require(["ace/ace"], function(a) {
20261 if (a) {
20262 a.config.init(true);
20263 a.define = window.define;
20264 }
20265 if (!window.ace)
20266 window.ace = a;
20267 for (var key in a) if (a.hasOwnProperty(key))
20268 window.ace[key] = a[key];
20269 });
20270 })();
20271